Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions backend/__fixtures__/cloudprofiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ const cloudProfileList = [
uid: 5,
name: 'infra3-profileName2',
kind: 'infra3'
}),
getCloudProfile({
uid: 6,
name: 'infra4-profileName',
kind: 'infra4',
seedSelector: {
providerTypes: ['*']
}
})
]

Expand Down
7 changes: 6 additions & 1 deletion backend/lib/routes/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ function sanitizeFrontendConfig (frontendConfig) {
} = {},
vendorHints = [],
resourceQuotaHelp = '',
controlPlaneHighAvailabilityHelp = ''
controlPlaneHighAvailabilityHelp = '',
customCloudProviders = {}
} = sanitizedFrontendConfig

convertAndSanitize(alert, 'message')
Expand Down Expand Up @@ -86,5 +87,9 @@ function sanitizeFrontendConfig (frontendConfig) {
convertAndSanitize(vendorHint, 'message')
}

for (const key of Object.keys(customCloudProviders)) {
convertAndSanitize(customCloudProviders[key]?.secret, 'help')
}

return sanitizedFrontendConfig
}
4 changes: 2 additions & 2 deletions backend/lib/services/cloudProviderSecrets.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const { Resources } = require('@gardener-dashboard/kube-client')
const createError = require('http-errors')
const { format: fmt } = require('util')
const { decodeBase64, encodeBase64 } = require('../utils')
const whitelistedPropertyKeys = ['accessKeyID', 'subscriptionID', 'project', 'domainName', 'tenantName', 'authUrl', 'vsphereUsername', 'nsxtUsername', 'USERNAME', 'metalAPIURL']
const whitelistedPropertyKeys = ['accesskeyid', 'subscriptionID', 'project', 'domainName', 'tenantName', 'authUrl', 'vsphereUsername', 'nsxtUsername', 'username', 'metalAPIURL']
const cloudprofiles = require('./cloudprofiles')
const shoots = require('./shoots')
const { getQuotas, findProjectByNamespace } = require('../cache')
Expand Down Expand Up @@ -44,7 +44,7 @@ function fromResource ({ secretBinding, cloudProviderKind, secret, quotas = [],

const iteratee = (value, key) => {
value = decodeBase64(value)
if (!_.includes(whitelistedPropertyKeys, key)) {
if (!_.includes(_.map(whitelistedPropertyKeys, _.toLower), _.toLower(key))) {
value = '****************'
}
return value
Expand Down
2 changes: 1 addition & 1 deletion backend/lib/services/cloudprofiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function assignSeedsToCloudProfileIteratee (seeds) {
return cloudProfileResource => {
function filterProviderType (seed) {
const seedProviderType = _.get(seed, 'spec.provider.type')
return _.includes(providerTypes, seedProviderType)
return _.includes(providerTypes, seedProviderType) || _.includes(providerTypes, '*')
}
const providerType = cloudProfileResource.spec.type
const matchLabels = _.get(cloudProfileResource, 'spec.seedSelector.matchLabels')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,38 @@ Array [
"name": "infra3-profileName2",
},
},
Object {
"data": Object {
"kubernetes": Object {
"versions": Array [
Object {
"version": "1.9.0",
},
Object {
"version": "1.8.5",
},
],
},
"seedNames": Array [
"infra1-seed",
"infra1-seed2",
"infra3-seed",
"infra4-seed-without-secretRef",
"infra3-seed-with-selector",
"infra3-seed-without-selector",
],
"seedSelector": Object {
"providerTypes": Array [
"*",
],
},
"type": "infra4",
},
"metadata": Object {
"cloudProviderKind": "infra4",
"displayName": "infra4-profileName",
"name": "infra4-profileName",
},
},
]
`;
1 change: 1 addition & 0 deletions docs/development/local-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ frontend:
The Gardener Dashboard [`backend`](https://github.com/gardener/dashboard/tree/master/backend) server requires a kubeconfig for the Garden cluster. You can set it e.g. by using the `KUBECONFIG` environment variable.

If you want to run the Garden cluster locally, follow the [getting started locally](https://github.com/gardener/gardener/blob/master/docs/development/getting_started_locally.md) documentation.
Gardener Dashboard supports the `local` infrastructure provider that comes with the local Gardener cluster setup. Please login to the Dashboard with a token of a service account that has cluster admin permission.

Concurrently run the `backend` server (port `3030`) and the [`frontend`](https://github.com/gardener/dashboard/tree/master/frontend) server (port `8080`) with hot reload enabled.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ export default {
return this.regionsWithoutSeedByCloudProfileName(this.cloudProfileName)
},
showAllRegions () {
return this.cfg.seedCandidateDeterminationStrategy && this.cfg.seedCandidateDeterminationStrategy !== 'SameRegion'
return this.cfg.seedCandidateDeterminationStrategy !== 'SameRegion'
},
regionItems () {
const regionItems = []
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/components/ShootWorkers/ManageWorkers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ SPDX-License-Identifier: Apache-2.0

<script>
import WorkerInputGeneric from '@/components/ShootWorkers/WorkerInputGeneric'
import { mapGetters } from 'vuex'
import { mapGetters, mapState } from 'vuex'
import { isZonedCluster } from '@/utils'
import { findFreeNetworks, getZonesNetworkConfiguration } from '@/utils/createShoot'
import forEach from 'lodash/forEach'
Expand Down Expand Up @@ -118,6 +118,9 @@ export default {
'generateWorker',
'expiringWorkerGroupsForShoot'
]),
...mapState([
'cfg'
]),
allMachineTypes () {
return this.machineTypesByCloudProfileName({ cloudProfileName: this.cloudProfileName })
},
Expand Down Expand Up @@ -311,7 +314,7 @@ export default {
* do not pass shootspec as we do not have it available in this component and it is (currently) not required to determine isZoned for new clusters. This event handler is only called for new clusters, as the
* userInterActionBus is only set for the create cluster use case
*/
this.zonedCluster = isZonedCluster({ cloudProviderKind: this.cloudProviderKind, isNewCluster: this.isNewCluster })
this.zonedCluster = isZonedCluster({ cloudProviderKind: this.cloudProviderKind, isNewCluster: this.isNewCluster, customCloudProviders: this.cfg.customCloudProviders })
Comment thread
grolu marked this conversation as resolved.
Outdated
this.setDefaultWorker()
})
this.userInterActionBus.on('updateRegion', region => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import { errorDetailsFromError } from '@/utils/error'
import { isZonedCluster } from '@/utils'
import get from 'lodash/get'
import cloneDeep from 'lodash/cloneDeep'
import { mapState } from 'vuex'
const ManageWorkers = () => import('@/components/ShootWorkers/ManageWorkers')
const ShootEditor = () => import('@/components/ShootEditor')

Expand Down Expand Up @@ -116,6 +117,9 @@ export default {
asyncRef('workerEditor')
],
computed: {
...mapState([
'cfg'
]),
tab: {
get () {
return this.tabValue
Expand Down Expand Up @@ -163,7 +167,7 @@ export default {
const zonesNetworkConfiguration = get(this.shootItem, 'spec.provider.infrastructureConfig.networks.zones')
const cloudProfileName = this.shootCloudProfileName
const region = this.shootRegion
const zonedCluster = isZonedCluster({ cloudProviderKind: this.shootCloudProviderKind, shootSpec: this.shootSpec })
const zonedCluster = isZonedCluster({ cloudProviderKind: this.shootCloudProviderKind, shootSpec: this.shootSpec, customCloudProviders: this.cfg.customCloudProviders })
Comment thread
grolu marked this conversation as resolved.
Outdated
const existingWorkerCIDR = get(this.shootItem, 'spec.networking.nodes')

await this.$manageWorkers.dispatch('setWorkersData', { workers, cloudProfileName, region, zonesNetworkConfiguration, zonedCluster, existingWorkerCIDR, kubernetesVersion: this.shootK8sVersion })
Expand Down
57 changes: 17 additions & 40 deletions frontend/src/components/VendorIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ SPDX-License-Identifier: Apache-2.0
</template>

<script>
import { mapState } from 'vuex'
import startsWith from 'lodash/startsWith'
import get from 'lodash/get'

export default {
props: {
Expand All @@ -30,60 +32,35 @@ export default {
}
},
computed: {
...mapState([
'cfg'
]),
iconSrc () {
switch (this.value) {
// infrastructures
case 'azure':
return require('@/assets/azure.svg')
case 'aws':
return require('@/assets/aws.svg')
case 'gcp':
return require('@/assets/gcp.svg')
case 'openstack':
return require('@/assets/openstack.svg')
case 'alicloud':
return require('@/assets/alicloud.svg')
case 'vsphere':
return require('@/assets/vsphere.svg')
case 'metal':
return require('@/assets/metal.svg')
const customCloudProviderIcon = get(this.cfg, ['customCloudProviders', this.value, 'icon'])
if (customCloudProviderIcon) {
return customCloudProviderIcon
}

// dns
case 'aws-route53':
return require('@/assets/aws-route53.svg')
case 'azure-dns':
// If filename is different from value you need to specify this below
switch (this.value) {
case 'azure-private-dns':
return require('@/assets/azure-dns.svg')
case 'google-clouddns':
return require('@/assets/google-clouddns.svg')
case 'openstack-designate':
return require('@/assets/openstack.svg')
case 'alicloud-dns':
return require('@/assets/alicloud-dns.png')
case 'cloudflare-dns':
return require('@/assets/cloudflare-dns.svg')
case 'infoblox-dns':
return require('@/assets/infoblox-dns.svg')
case 'netlify-dns':
return require('@/assets/netlify-dns.svg')

// os
case 'coreos':
return require('@/assets/coreos.svg')
case 'suse-jeos':
return require('@/assets/suse.svg')
case 'suse-chost':
return require('@/assets/suse.svg')
case 'ubuntu':
return require('@/assets/ubuntu.svg')
case 'gardenlinux':
return require('@/assets/gardenlinux.svg')
case 'flatcar':
return require('@/assets/flatcar.svg')
case 'hcloud':
return require('@/assets/hcloud.svg')
}
return undefined

try {
return require(`@/assets/${this.value}.svg`)
Copy link
Copy Markdown
Member

@holgerkoser holgerkoser Mar 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested this. I think it will not work as expected because there is a webpack build step involved which creates hash values for the assets and returns a pathname with the hash value. In this case webpack cannot know the path and the require will not work at runtime??

Copy link
Copy Markdown
Member Author

@grolu grolu Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are probably right. I did not think about the webpack build step. I need to adjust this anyway to support images mounted via configuration. I will revert the other changes
Edit: I checked this with a production build and it seems to work... although I'm actually not sure why. Maybe we should not do it anyway as I do not have a good feeling about this.

} catch (err) {
return undefined
}
},
isMdiIcon () {
return startsWith(this.value, 'mdi-')
Expand Down
Loading