feat: Add temporary argo scaffolder plugin that creates an argo application
This commit is contained in:
parent
58f3fa8625
commit
b76fbfc34a
@ -48,7 +48,7 @@ proxy:
|
||||
# Set this variable by using this command
|
||||
# export ARGOCD_AUTH_TOKEN="argocd.token=$(argocd --server argocd-server-sreez.apps.oc-med.wk.nt.local:443 --insecure account generate-token --account backstage)"
|
||||
# Use the appropriate account as configured in your argo-cm deployment ConfigMap
|
||||
$env: ARGOCD_AUTH_TOKEN
|
||||
$env: BACKSTAGE_ARGOCD_AUTH_TOKEN
|
||||
### Example for how to add a proxy endpoint for the frontend.
|
||||
### A typical reason to do this is to handle HTTPS and CORS for internal services.
|
||||
# endpoints:
|
||||
|
@ -49,4 +49,30 @@ backend.add(import('@backstage/plugin-search-backend/alpha'));
|
||||
|
||||
backend.add(import('@backstage/plugin-devtools-backend'));
|
||||
|
||||
import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
import { createNewFileAction } from './plugins/scaffolder/actions/custom';
|
||||
import { createArgoProjectAction } from './plugins/scaffolder/actions/argo';
|
||||
|
||||
const scaffolderModuleCustomExtensions = createBackendModule({
|
||||
pluginId: 'scaffolder', // name of the plugin that the module is targeting
|
||||
moduleId: 'custom-extensions',
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
scaffolder: scaffolderActionsExtensionPoint,
|
||||
// ... and other dependencies as needed
|
||||
},
|
||||
async init({ scaffolder /* ..., other dependencies */ }) {
|
||||
// Here you have the opportunity to interact with the extension
|
||||
// point before the plugin itself gets instantiated
|
||||
scaffolder.addActions(createNewFileAction()); // just an example
|
||||
scaffolder.addActions(createArgoProjectAction()); // just an example
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
backend.add(scaffolderModuleCustomExtensions());
|
||||
|
||||
backend.start();
|
||||
|
@ -0,0 +1,69 @@
|
||||
import { exec } from 'child_process';
|
||||
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const createArgoProjectAction = () => {
|
||||
return createTemplateAction({
|
||||
id: 'argocd:app:create',
|
||||
schema: {
|
||||
input: z.object({
|
||||
appName: z.string().describe('The name of the application'),
|
||||
argoInstance: z.string().describe('The ARGO instance URL'),
|
||||
namespace: z.string().describe('The Kubernetes namespace'),
|
||||
repoUrl: z.string().describe('The repository URL to publish the artifacts'),
|
||||
repoPath: z.string().describe('The path in the repository that argo must watch'),
|
||||
labelValue: z.string().describe('The value for the label based on the app name'),
|
||||
valuesFiles: z.array(z.string()).describe('List of value files'),
|
||||
}),
|
||||
},
|
||||
|
||||
async handler(ctx) {
|
||||
createArgoProject(ctx.input)
|
||||
// throw new Error(`Yay we are in handler with ctx ${ctx}`)
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
type ArgoProjectParams = {
|
||||
appName: string;
|
||||
argoInstance: string;
|
||||
namespace: string;
|
||||
repoUrl: string;
|
||||
repoPath: string;
|
||||
labelValue: string;
|
||||
valuesFiles: string[];
|
||||
}
|
||||
|
||||
function createArgoProject(params: ArgoProjectParams): void {
|
||||
const command = `argocd app create ${params.appName} --project default --repo ${params.repoUrl} --path ${params.repoPath} --dest-server https://kubernetes.default.svc --dest-namespace ${params.namespace} --sync-policy auto`;
|
||||
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`exec error: ${error}`);
|
||||
throw new Error(`createArgoProject failed due to ${error}`);
|
||||
}
|
||||
|
||||
console.log(`stdout: ${stdout}`);
|
||||
console.error(`stderr: ${stderr}`);
|
||||
});
|
||||
|
||||
executeWithRetry(command, 1, 5); // Start the retry mechanism with the first attempt
|
||||
}
|
||||
|
||||
|
||||
function executeWithRetry(command: string, attempt: number, maxAttemps: number = 5): void {
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`exec error on attempt ${attempt}: ${error}`);
|
||||
|
||||
// If it's not the last retry, wait for 2 seconds and try again
|
||||
if (attempt < maxAttemps) {
|
||||
setTimeout(() => executeWithRetry(command, attempt + 1, maxAttemps), 2000);
|
||||
} else {
|
||||
console.error(`Failed after ${attempt} attempts: ${stderr}`);
|
||||
}
|
||||
} else {
|
||||
console.log(`stdout: ${stdout}`);
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const createNewFileAction = () => {
|
||||
return createTemplateAction({
|
||||
id: 'acme:file:create',
|
||||
schema: {
|
||||
input: z.object({
|
||||
contents: z.string().describe('The contents of the file'),
|
||||
filename: z
|
||||
.string()
|
||||
.describe('The filename of the file that will be created'),
|
||||
}),
|
||||
},
|
||||
|
||||
async handler(ctx) {
|
||||
throw new Error(`Yay we are in handler with ctx ${ctx}`)
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -9287,9 +9287,9 @@
|
||||
integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==
|
||||
|
||||
"@types/react-dom@*", "@types/react-dom@^18", "@types/react-dom@^18.0.0":
|
||||
version "18.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0"
|
||||
integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==
|
||||
version "18.2.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.25.tgz#2946a30081f53e7c8d585eb138277245caedc521"
|
||||
integrity sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
@ -9325,9 +9325,9 @@
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^16.13.1 || ^17.0.0", "@types/react@^16.13.1 || ^17.0.0 || ^18.0.0", "@types/react@^18":
|
||||
version "18.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.1.tgz#fed43985caa834a2084d002e4771e15dfcbdbe8e"
|
||||
integrity sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==
|
||||
version "18.2.79"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.79.tgz#c40efb4f255711f554d47b449f796d1c7756d865"
|
||||
integrity sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
csstype "^3.0.2"
|
||||
@ -23238,7 +23238,16 @@ string-length@^4.0.1:
|
||||
char-regex "^1.0.2"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@ -23316,7 +23325,7 @@ string_decoder@~1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0, strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
@ -23330,6 +23339,13 @@ strip-ansi@5.2.0:
|
||||
dependencies:
|
||||
ansi-regex "^4.1.0"
|
||||
|
||||
strip-ansi@6.0, strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^7.0.1:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
|
||||
@ -25183,7 +25199,7 @@ wordwrap@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
@ -25201,6 +25217,15 @@ wrap-ansi@^6.0.1:
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
||||
|
Loading…
Reference in New Issue
Block a user