Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Provider Credentials #2195

Merged
merged 43 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
b116c6e
Refactor Provider Credentials WIP
grolu Nov 21, 2024
452ba29
Merge branch 'master' into enh/refactor-secrets
grolu Nov 21, 2024
3ce41cd
rm unused function
grolu Nov 21, 2024
832c217
Merge branch 'enh/refactor-secrets' of github.com:gardener/dashboard …
grolu Nov 21, 2024
1c6a00d
Some cleanup
grolu Nov 21, 2024
8c08bd0
Some fixes
grolu Nov 21, 2024
b4c0e22
use composable for shared secret data
grolu Nov 22, 2024
0dda694
Merge branch 'master' into enh/refactor-secrets
grolu Nov 26, 2024
5b82bcd
PR Feedback
grolu Nov 27, 2024
e43a45f
Adapted frontend tests
grolu Nov 27, 2024
35d8c59
Adapted backend tests
grolu Nov 27, 2024
396e122
Return secretbindings, secrets, quotas as separate lists
grolu Nov 29, 2024
36bc5ed
Merge branch 'master' into enh/refactor-secrets
grolu Dec 2, 2024
cee31b0
Use lodash chaining to resolve secretbinding quotas
grolu Dec 2, 2024
46a29e8
Merge branch 'master' into enh/refactor-secrets
grolu Dec 2, 2024
8843799
PR Feedback 1
grolu Dec 3, 2024
24bdd56
Merge branch 'enh/refactor-secrets' of github.com:gardener/dashboard …
grolu Dec 3, 2024
c792b6f
- Create and Update Secret resources using `stringData`
grolu Dec 10, 2024
7ad5255
Create Secret and SecretBinding resources in Frontend
grolu Dec 18, 2024
d427a23
Merge branch 'master' into enh/refactor-secrets
grolu Dec 18, 2024
19e9497
Fixed minor things
grolu Dec 18, 2024
4d8424e
Merge branch 'master' into enh/refactor-secrets
grolu Jan 16, 2025
232f27a
Merge branch 'master' into enh/refactor-secrets
grolu Jan 16, 2025
e731806
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
c34b566
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
a73647f
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
71abea5
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
d795fbb
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
4fa0053
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
7715a9c
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
aa65e6f
PR Feedback 1
grolu Jan 17, 2025
53f7e43
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
a951738
Merge branch 'master' into enh/refactor-secrets
grolu Jan 17, 2025
94b122f
PR Feedback 2
grolu Jan 20, 2025
cb88a69
Merge branch 'enh/refactor-secrets' of github.com:gardener/dashboard …
grolu Jan 20, 2025
e438117
PR Feedback 3
grolu Jan 20, 2025
cfd633a
Fixed error on details page when accessing ._secret
grolu Jan 20, 2025
2eafdc6
PR Feedback
grolu Jan 20, 2025
e4968fc
PR Feedback
grolu Jan 21, 2025
3aec2d2
use useUrlSearchParams
grolu Jan 22, 2025
0c20607
PR Feedback
grolu Jan 22, 2025
00f52b3
Merge branch 'master' into enh/refactor-secrets
grolu Jan 22, 2025
4cb107b
Merge branch 'master' into enh/refactor-secrets
grolu Jan 23, 2025
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
48 changes: 48 additions & 0 deletions backend/lib/routes/cloudProviderCredentials.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0
//

'use strict'

const express = require('express')
const { cloudProviderCredentials } = require('../services')
const { metricsRoute } = require('../middleware')
const { UnprocessableEntity } = require('http-errors')

const router = module.exports = express.Router({
mergeParams: true,
})

const metricsMiddleware = metricsRoute('cloudProviderCredentials')

router.route('/')
.all(metricsMiddleware)
.post(async (req, res, next) => {
try {
const user = req.user
const { method, params } = req.body

let credentialOperation
switch (method) {
case 'list':
credentialOperation = cloudProviderCredentials.list
break
case 'create':
credentialOperation = cloudProviderCredentials.create
break
case 'patch':
credentialOperation = cloudProviderCredentials.patch
break
case 'remove':
credentialOperation = cloudProviderCredentials.remove
break
default:
throw new UnprocessableEntity(`${method} not allowed for cloud provider credentials`)
}
res.send(await credentialOperation.call(cloudProviderCredentials, { user, params }))
} catch (err) {
next(err)
}
})
60 changes: 0 additions & 60 deletions backend/lib/routes/cloudProviderSecrets.js

This file was deleted.

2 changes: 1 addition & 1 deletion backend/lib/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ module.exports = {
'/projects': require('./projects'),
'/namespaces/:namespace/shoots': require('./shoots'),
'/namespaces/:namespace/tickets': require('./tickets'),
'/namespaces/:namespace/cloudprovidersecrets': require('./cloudProviderSecrets'),
'/cloudprovidercredentials': require('./cloudProviderCredentials'),
'/namespaces/:namespace/members': require('./members'),
'/namespaces/:namespace/resourcequotas': require('./resourceQuotas'),
}
Expand Down
138 changes: 138 additions & 0 deletions backend/lib/services/cloudProviderCredentials.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
//
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0
//

const _ = require('lodash')
const { getQuotas } = require('../cache')
const createError = require('http-errors')
const logger = require('../logger')

exports.list = async function ({ user, params }) {
const client = user.client
const { bindingNamespace } = params

const [
{ items: secretBindings },
{ items: secrets },
] = await Promise.all([
client['core.gardener.cloud'].secretbindings.list(bindingNamespace),
client.core.secrets.list(bindingNamespace, { labelSelector: 'reference.gardener.cloud/secretbinding=true' }),
])

const pickQuotaProperties = _.partialRight(_.pick, [
'apiVersion',
'kind',
'metadata.name',
'metadata.namespace',
'metadata.uid',
'spec.scope',
'spec.clusterLifetimeDays',
])

const quotas = _
.chain(secretBindings)
.flatMap(resolveQuotas)
.uniqBy('metadata.uid')
.filter('spec.clusterLifetimeDays')
.map(pickQuotaProperties)
.value()

return {
secretBindings,
secrets,
quotas,
}
}

exports.create = async function ({ user, params }) {
const client = user.client

let { secret, secretBinding } = params
const secretNamespace = secret.metadata.namespace
const bindingNamespace = secretBinding.metadata.namespace
const secretRefNamespace = secretBinding.secretRef.namespace

if (bindingNamespace !== secretRefNamespace ||
secretRefNamespace !== secretNamespace) {
throw createError(422, 'Create allowed if secret and secretBinding are in the same namespace')
}

secret = await client.core.secrets.create(secretNamespace, secret)

try {
secretBinding = await client['core.gardener.cloud'].secretbindings.create(bindingNamespace, secretBinding)
} catch (err) {
logger.error('failed to create SecretBinding, cleaning up secret %s/%s', secret.metadata.namespace, secret.metadata.name)
await client.core.secrets.delete(secret.metadata.namespace, secret.metadata.name)

throw err
}

return {
secretBinding,
secret,
quotas: resolveQuotas(secretBinding),
}
}

exports.patch = async function ({ user, params }) {
const client = user.client

let { secret, secretBinding } = params
const secretNamespace = secret.metadata.namespace
const secretName = secret.metadata.name
const bindingNamespace = secretBinding.metadata.namespace
const secretBindingName = secretBinding.metadata.name
const secretRefNamespace = secretBinding.secretRef.namespace

secretBinding = await client['core.gardener.cloud'].secretbindings.get(bindingNamespace, secretBindingName)
if (!secretBinding) {
throw createError(404)
}
if (bindingNamespace !== secretRefNamespace ||
secretRefNamespace !== secretNamespace) {
throw createError(422, 'Patch allowed only if secret and secretBinding are in the same namespace')
}
secret = await client.core.secrets.update(bindingNamespace, secretName, secret)

return {
secretBinding,
secret,
quotas: resolveQuotas(secretBinding),
}
}

exports.remove = async function ({ user, params }) {
const client = user.client
const { bindingNamespace, secretBindingName } = params

const secretBinding = await client['core.gardener.cloud'].secretbindings.get(bindingNamespace, secretBindingName)
if (!secretBinding) {
throw createError(404)
}
if (secretBinding.metadata.namespace !== secretBinding.secretRef.namespace) {
throw createError(422, 'Remove allowed only if secret and secretBinding are in the same namespace')
}

const secretRef = secretBinding.secretRef
await Promise.all([
await client['core.gardener.cloud'].secretbindings.delete(bindingNamespace, secretBindingName),
await client.core.secrets.delete(secretRef.namespace, secretRef.name),
])
}

function resolveQuotas (secretBinding) {
const quotas = getQuotas()
const findQuota = ({ namespace, name } = {}) => _.find(quotas, ({ metadata }) => metadata.namespace === namespace && metadata.name === name)
try {
return _
.chain(secretBinding.quotas)
.map(findQuota)
.compact()
.value()
} catch (err) {
return []
}
}
Loading
Loading