From 250ae4edd47385b7c76a428e2f6d7e2b5de6caed Mon Sep 17 00:00:00 2001 From: srodenhuis Date: Wed, 16 Aug 2023 10:39:54 +0200 Subject: [PATCH 1/6] feat: copy certs for argo --- src/tasks/otomi/copy-certs-argo.ts | 99 ++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/tasks/otomi/copy-certs-argo.ts diff --git a/src/tasks/otomi/copy-certs-argo.ts b/src/tasks/otomi/copy-certs-argo.ts new file mode 100644 index 00000000..4b62711b --- /dev/null +++ b/src/tasks/otomi/copy-certs-argo.ts @@ -0,0 +1,99 @@ +import { V1Secret, V1SecretList } from '@kubernetes/client-node' +import { IncomingMessage } from 'http' +import { k8s } from '../../k8s' +import { cleanEnv, TEAM_IDS } from '../../validators' + +const env = cleanEnv({ + TEAM_IDS, +}) + +const targetNamespace = 'argocd' + +const processed: string[] = [] + +export const targetPullSecretsFilter = ({ metadata }: V1Secret): boolean => metadata!.name!.indexOf(`copy-`) === 0 + +// Returns list of names of all pull secrets in the target namespace that were created before. +export const getTargetPullSecretNames = async (): Promise => { + const targetPullSecretsRes = await k8s + .core() + .listNamespacedSecret(targetNamespace, undefined, undefined, undefined, 'type=kubernetes.io/dockerconfigjson') + const { body: pullSecrets }: { body: V1SecretList } = targetPullSecretsRes + const targetPullSecretNames = pullSecrets.items + .filter(targetPullSecretsFilter) + .map((s: V1Secret) => s.metadata!.name!) + console.debug(`Found the following pull secrets in the namespace "${targetNamespace}": ${targetPullSecretNames}`) + return targetPullSecretNames +} + +export const createTargetPullSecret = ( + name: string, + teamId: string, + data: Record, +): Promise<{ response: IncomingMessage; body: V1Secret }> => { + console.info(`Creating Pull secret "${targetNamespace}/${name}"`) + const newSecret: V1Secret = { + ...new V1Secret(), + metadata: { + namespace: targetNamespace, + name, + annotations: { + 'app.kubernetes.io/managed-by': 'otomi', + 'log.otomi.io/copied-from-namespace': teamId, + }, + }, + type: 'kubernetes.io/dockerconfigjson', + data, + } + return k8s.core().createNamespacedSecret(targetNamespace, newSecret) +} + +export const copyTeamPullSecrets = async (teamId: string, targetPullSecretNames: string[]): Promise => { + console.info(`Copying Pull secrets from team-${teamId} to ${targetNamespace} namespace`) + const namespace = `team-${teamId}` + const getTargetSecretName = (name) => `copy-${teamId}-${name}` + // get all target namespace Pull secrets + const { + body: { items: teamPullSecrets }, + } = await k8s + .core() + .listNamespacedSecret(namespace, undefined, undefined, undefined, 'type=kubernetes.io/dockerconfigjson') + // create new ones if not existing + await Promise.all( + teamPullSecrets + .filter(({ metadata }) => !targetPullSecretNames.includes(getTargetSecretName(metadata!.name))) + .map(({ metadata, data }) => { + const name = getTargetSecretName(metadata!.name) + return createTargetPullSecret(name, teamId, data as Record) + }), + ) + console.info(`Finished copying Pull secrets from team-${teamId}`) + // update processed list for pruning later + teamPullSecrets.map(({ metadata }) => processed.push(getTargetSecretName(metadata!.name as string))) +} + +export const prunePullSecrets = async (targetPullSecretNames: string[]): Promise => { + const prunableTargetSecrets = targetPullSecretNames.filter((name) => !processed.includes(name)) + await Promise.all( + prunableTargetSecrets.map((name) => { + console.info(`Pruning Harbor pull secret "${targetNamespace}/${name}"`) + return k8s.core().deleteNamespacedSecret(name, targetNamespace) + }), + ) +} + +const main = async (): Promise => { + try { + const targetPullSecretNames = await getTargetPullSecretNames() + await Promise.all( + env.TEAM_IDS.map((teamId) => { + return copyTeamPullSecrets(teamId, targetPullSecretNames) + }), + ) + await prunePullSecrets(targetPullSecretNames) + } catch (e) { + throw new Error(`One or more errors occurred copying pull secrets: ${JSON.stringify(e)}`) + } +} + +main() From dc95c25a76dc91a3571b2ba1d2a5c488a182b2fc Mon Sep 17 00:00:00 2001 From: srodenhuis Date: Wed, 16 Aug 2023 11:37:56 +0200 Subject: [PATCH 2/6] fix: add task argo --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index ca1d9ec5..1e219ed3 100644 --- a/package.json +++ b/package.json @@ -121,6 +121,7 @@ "tasks:certs-aws": "node dist/tasks/otomi/certs-aws.js", "tasks:copy-certs-dev": "ts-node-dev ./src/tasks/otomi/copy-certs.ts", "tasks:copy-certs": "node dist/tasks/otomi/copy-certs.js", + "tasks:copy-certs-argo": "node dist/tasks/otomi/copy-certs-argo.js", "tasks:drone-dev": "ts-node-dev ./src/tasks/drone/drone.ts", "tasks:drone": "node dist/tasks/drone/drone.js", "tasks:gitea-dev": "NODE_TLS_REJECT_UNAUTHORIZED=0 ts-node-dev ./src/tasks/gitea/gitea.ts && ts-node-dev ./src/tasks/gitea/gitea-drone-oauth.ts", From a7e918edecdf8ae679f5cf43ce832416f4a59fe6 Mon Sep 17 00:00:00 2001 From: srodenhuis Date: Wed, 16 Aug 2023 11:54:01 +0200 Subject: [PATCH 3/6] fix: filter --- src/tasks/otomi/copy-certs-argo.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tasks/otomi/copy-certs-argo.ts b/src/tasks/otomi/copy-certs-argo.ts index 4b62711b..fa60491a 100644 --- a/src/tasks/otomi/copy-certs-argo.ts +++ b/src/tasks/otomi/copy-certs-argo.ts @@ -11,7 +11,8 @@ const targetNamespace = 'argocd' const processed: string[] = [] -export const targetPullSecretsFilter = ({ metadata }: V1Secret): boolean => metadata!.name!.indexOf(`copy-`) === 0 +export const targetPullSecretsFilter = ({ metadata }: V1Secret): boolean => + metadata!.name!.indexOf(`copy-`) === 0 && metadata!.name === 'harbor-pullsecret' // Returns list of names of all pull secrets in the target namespace that were created before. export const getTargetPullSecretNames = async (): Promise => { @@ -51,7 +52,7 @@ export const createTargetPullSecret = ( export const copyTeamPullSecrets = async (teamId: string, targetPullSecretNames: string[]): Promise => { console.info(`Copying Pull secrets from team-${teamId} to ${targetNamespace} namespace`) const namespace = `team-${teamId}` - const getTargetSecretName = (name) => `copy-${teamId}-${name}` + const getTargetSecretName = (name) => `copy-team-${teamId}-${name}` // get all target namespace Pull secrets const { body: { items: teamPullSecrets }, From 3ba0fa70b23f778056069e73082c079643234c8d Mon Sep 17 00:00:00 2001 From: srodenhuis Date: Wed, 16 Aug 2023 13:10:17 +0200 Subject: [PATCH 4/6] fix: filter source ns --- src/tasks/otomi/copy-certs-argo.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tasks/otomi/copy-certs-argo.ts b/src/tasks/otomi/copy-certs-argo.ts index fa60491a..9970b7b4 100644 --- a/src/tasks/otomi/copy-certs-argo.ts +++ b/src/tasks/otomi/copy-certs-argo.ts @@ -11,8 +11,7 @@ const targetNamespace = 'argocd' const processed: string[] = [] -export const targetPullSecretsFilter = ({ metadata }: V1Secret): boolean => - metadata!.name!.indexOf(`copy-`) === 0 && metadata!.name === 'harbor-pullsecret' +export const targetPullSecretsFilter = ({ metadata }: V1Secret): boolean => metadata!.name!.indexOf(`copy-`) === 0 // Returns list of names of all pull secrets in the target namespace that were created before. export const getTargetPullSecretNames = async (): Promise => { @@ -53,12 +52,19 @@ export const copyTeamPullSecrets = async (teamId: string, targetPullSecretNames: console.info(`Copying Pull secrets from team-${teamId} to ${targetNamespace} namespace`) const namespace = `team-${teamId}` const getTargetSecretName = (name) => `copy-team-${teamId}-${name}` - // get all target namespace Pull secrets + // get all team namespace Pull secrets const { body: { items: teamPullSecrets }, } = await k8s .core() - .listNamespacedSecret(namespace, undefined, undefined, undefined, 'type=kubernetes.io/dockerconfigjson') + .listNamespacedSecret( + namespace, + undefined, + undefined, + undefined, + 'type=kubernetes.io/dockerconfigjson', + 'metadata.name=harbor-pullsecret', + ) // create new ones if not existing await Promise.all( teamPullSecrets From 5562bd60982a1dbfe5cb11e797518a1f3c9ed6b8 Mon Sep 17 00:00:00 2001 From: srodenhuis Date: Wed, 16 Aug 2023 13:42:39 +0200 Subject: [PATCH 5/6] fix: filter source name --- src/tasks/otomi/copy-certs-argo.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/tasks/otomi/copy-certs-argo.ts b/src/tasks/otomi/copy-certs-argo.ts index 9970b7b4..f83e4aa6 100644 --- a/src/tasks/otomi/copy-certs-argo.ts +++ b/src/tasks/otomi/copy-certs-argo.ts @@ -51,20 +51,14 @@ export const createTargetPullSecret = ( export const copyTeamPullSecrets = async (teamId: string, targetPullSecretNames: string[]): Promise => { console.info(`Copying Pull secrets from team-${teamId} to ${targetNamespace} namespace`) const namespace = `team-${teamId}` + const secretName = `harbor-pullsecret` const getTargetSecretName = (name) => `copy-team-${teamId}-${name}` // get all team namespace Pull secrets const { body: { items: teamPullSecrets }, } = await k8s .core() - .listNamespacedSecret( - namespace, - undefined, - undefined, - undefined, - 'type=kubernetes.io/dockerconfigjson', - 'metadata.name=harbor-pullsecret', - ) + .listNamespacedSecret(namespace, secretName, undefined, undefined, 'type=kubernetes.io/dockerconfigjson') // create new ones if not existing await Promise.all( teamPullSecrets From 2eed422738a61d322752686b0060c914ea974667 Mon Sep 17 00:00:00 2001 From: srodenhuis Date: Thu, 17 Aug 2023 20:08:11 +0200 Subject: [PATCH 6/6] fix: rm att --- src/tasks/otomi/copy-certs-argo.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tasks/otomi/copy-certs-argo.ts b/src/tasks/otomi/copy-certs-argo.ts index f83e4aa6..50a4f017 100644 --- a/src/tasks/otomi/copy-certs-argo.ts +++ b/src/tasks/otomi/copy-certs-argo.ts @@ -51,14 +51,13 @@ export const createTargetPullSecret = ( export const copyTeamPullSecrets = async (teamId: string, targetPullSecretNames: string[]): Promise => { console.info(`Copying Pull secrets from team-${teamId} to ${targetNamespace} namespace`) const namespace = `team-${teamId}` - const secretName = `harbor-pullsecret` const getTargetSecretName = (name) => `copy-team-${teamId}-${name}` // get all team namespace Pull secrets const { body: { items: teamPullSecrets }, } = await k8s .core() - .listNamespacedSecret(namespace, secretName, undefined, undefined, 'type=kubernetes.io/dockerconfigjson') + .listNamespacedSecret(namespace, undefined, undefined, undefined, 'type=kubernetes.io/dockerconfigjson') // create new ones if not existing await Promise.all( teamPullSecrets