wip
This commit is contained in:
parent
f581e1a45d
commit
4e04538e18
2 changed files with 73 additions and 66 deletions
|
@ -1,4 +1,4 @@
|
|||
import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
|
||||
import {KubernetesBuilder, OidcKubernetesAuthTranslator} from '@backstage/plugin-kubernetes-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
import { CatalogClient } from '@backstage/catalog-client';
|
||||
|
@ -11,6 +11,9 @@ export default async function createPlugin(
|
|||
logger: env.logger,
|
||||
config: env.config,
|
||||
catalogApi,
|
||||
permissions: env.permissions
|
||||
}).build();
|
||||
|
||||
new OidcKubernetesAuthTranslator()
|
||||
return router;
|
||||
}
|
||||
|
|
|
@ -3,12 +3,11 @@ import { Config } from '@backstage/config';
|
|||
import * as k8s from '@kubernetes/client-node';
|
||||
import {Logger} from "winston";
|
||||
import {HttpError} from "@kubernetes/client-node";
|
||||
import {useApi} from "@backstage/core-plugin-api";
|
||||
import {OidcKubernetesAuthTranslator} from "@backstage/plugin-kubernetes-backend";
|
||||
|
||||
type argoInput = {
|
||||
namespace: string
|
||||
clusterName: string
|
||||
userOIDCToken: string
|
||||
templateName: string
|
||||
parameters: parameter[]
|
||||
wait?: boolean
|
||||
|
@ -100,9 +99,14 @@ export function createInvokeArgoAction(config: Config, logger: Logger) {
|
|||
description: 'Name of Cluster',
|
||||
type: 'string',
|
||||
},
|
||||
userOIDCToken: {
|
||||
title: 'User\'s OIDC token',
|
||||
description: "If specified, it will use the provided token to communicate with the Kubernetes cluster",
|
||||
type: 'string'
|
||||
},
|
||||
templateName: {
|
||||
title: 'Template name',
|
||||
description: 'Argo Workflows template name',
|
||||
description: 'Argo Workflows template name to run',
|
||||
type: 'string',
|
||||
},
|
||||
parameters: {
|
||||
|
@ -123,7 +127,7 @@ export function createInvokeArgoAction(config: Config, logger: Logger) {
|
|||
},
|
||||
wait: {
|
||||
title: 'Wait for completion',
|
||||
description: 'specify weather to wait for completion of this workflow',
|
||||
description: 'specify weather to wait for completion of this workflow.',
|
||||
type: 'boolean',
|
||||
}
|
||||
},
|
||||
|
@ -145,78 +149,78 @@ export function createInvokeArgoAction(config: Config, logger: Logger) {
|
|||
async handler(ctx: ActionContext<argoInput>) {
|
||||
logger.debug(`Invoked with ${JSON.stringify(ctx.input)})`)
|
||||
logger.info(JSON.stringify(ctx.secrets))
|
||||
// const targetCluster = getClusterConfig(ctx.input.clusterName, config)
|
||||
// const kc = new k8s.KubeConfig()
|
||||
// kc.addCluster({
|
||||
// name: ctx.input.clusterName,
|
||||
// caData: targetCluster.getString("caData"),
|
||||
// server: targetCluster.getString("url"),
|
||||
// skipTLSVerify: targetCluster.getBoolean("skipTLSVerify"),
|
||||
// })
|
||||
// kc.addUser({
|
||||
// name: "admin",
|
||||
// token: targetCluster.getString("serviceAccountToken")
|
||||
// })
|
||||
// kc.addContext({
|
||||
// cluster: ctx.input.clusterName,
|
||||
// user: "admin",
|
||||
// name: ctx.input.clusterName
|
||||
// })
|
||||
// kc.setCurrentContext(ctx.input.clusterName)
|
||||
//
|
||||
// const client = kc.makeApiClient(k8s.CustomObjectsApi)
|
||||
// const wf = new Workflow(ctx.input.templateName, ctx.input.namespace, ctx.input.parameters)
|
||||
// // const body = generateBody(ctx.input.templateName, ctx.input.namespace)
|
||||
// try {
|
||||
// const resp = await client.createNamespacedCustomObject(
|
||||
// argoWorkflowsGroup, argoWorkflowsVersion, ctx.input.namespace,
|
||||
// argoWorkFlowPlural, wf
|
||||
// )
|
||||
// const respBody = resp.body as Workflow
|
||||
// logger.debug(`Workflow ID: ${respBody.metadata.name}, namespace ${respBody.metadata.namespace}`)
|
||||
// ctx.output('workflowName', respBody.metadata.name!)
|
||||
// ctx.output('workflowNamespace', respBody.metadata.namespace!)
|
||||
// if (ctx.input.wait) {
|
||||
// await wait(kc, respBody.metadata.namespace!, respBody.metadata.name!)
|
||||
// }
|
||||
// } catch (err) {
|
||||
// if (err instanceof HttpError) {
|
||||
// let msg = `${err.response.statusMessage}: `
|
||||
// if ("kind" in err.body && err.body.kind === "Status" && "message" in err.body) {
|
||||
// msg += err.body.message
|
||||
// }
|
||||
// logger.info(`error : ${err.response.statusCode} ${msg}`)
|
||||
// throw new Error(`Failed to talk to the cluster: ${err.response.statusCode} ${err.response.statusMessage} \n ${msg}`)
|
||||
// }
|
||||
// if (err instanceof Error) {
|
||||
// logger.error(`error while talking to cluster: ${err.name} ${err.message}`)
|
||||
// }
|
||||
// throw new Error("Unknown exception was encountered.")
|
||||
// }
|
||||
const targetCluster = getClusterConfig(ctx.input.clusterName, config)
|
||||
const kc = new k8s.KubeConfig()
|
||||
kc.addCluster({
|
||||
name: targetCluster.getString("name"),
|
||||
caData: targetCluster.getString("caData"),
|
||||
server: targetCluster.getString("url"),
|
||||
skipTLSVerify: targetCluster.getBoolean("skipTLSVerify"),
|
||||
})
|
||||
|
||||
kc.addUser({
|
||||
name: "scaffolder-user",
|
||||
token: ctx.input.userOIDCToken? ctx.input.userOIDCToken : targetCluster.getString("serviceAccountToken")
|
||||
})
|
||||
kc.addContext({
|
||||
cluster: ctx.input.clusterName,
|
||||
user: "scaffolder-user",
|
||||
name: ctx.input.clusterName
|
||||
})
|
||||
kc.setCurrentContext(ctx.input.clusterName)
|
||||
|
||||
const client = kc.makeApiClient(k8s.CustomObjectsApi)
|
||||
const wf = new Workflow(ctx.input.templateName, ctx.input.namespace, ctx.input.parameters)
|
||||
// const body = generateBody(ctx.input.templateName, ctx.input.namespace)
|
||||
try {
|
||||
const resp = await client.createNamespacedCustomObject(
|
||||
argoWorkflowsGroup, argoWorkflowsVersion, ctx.input.namespace,
|
||||
argoWorkFlowPlural, wf
|
||||
)
|
||||
const respBody = resp.body as Workflow
|
||||
logger.debug(`Workflow ID: ${respBody.metadata.name}, namespace ${respBody.metadata.namespace}`)
|
||||
ctx.output('workflowName', respBody.metadata.name!)
|
||||
ctx.output('workflowNamespace', respBody.metadata.namespace!)
|
||||
if (ctx.input.wait) {
|
||||
await wait(kc, respBody.metadata.namespace!, respBody.metadata.name!)
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof HttpError) {
|
||||
let msg = `${err.response.statusMessage}: `
|
||||
if ("kind" in err.body && err.body.kind === "Status" && "message" in err.body) {
|
||||
msg += err.body.message
|
||||
}
|
||||
logger.info(`error : ${err.response.statusCode} ${msg}`)
|
||||
throw new Error(`Failed to talk to the cluster: ${err.response.statusCode} ${err.response.statusMessage} \n ${msg}`)
|
||||
}
|
||||
if (err instanceof Error) {
|
||||
logger.error(`error while talking to cluster: ${err.name} ${err.message}`)
|
||||
}
|
||||
throw new Error("Unknown exception was encountered.")
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function getClusterConfig(name: string, config: Config): Config {
|
||||
const at = new OidcKubernetesAuthTranslator();
|
||||
|
||||
const c = config.getConfigArray("kubernetes.clusterLocatorMethods")
|
||||
const cc = c.filter(function(val) {
|
||||
return val.getString("type") === "config"
|
||||
})
|
||||
|
||||
const clusterConfigs = config.getConfigArray("kubernetes.clusterLocatorMethods").filter(
|
||||
(val: Config) => {
|
||||
return val.getString('type') === 'config'
|
||||
}
|
||||
)
|
||||
|
||||
const clusters = new Array<Config>();
|
||||
// this is shit
|
||||
cc.forEach(function(conf ) {
|
||||
const cl = conf.getConfigArray("clusters")
|
||||
cl.forEach(function(val) {
|
||||
if (val.getString("name") === name) {
|
||||
clusters.push(val)
|
||||
}
|
||||
clusterConfigs.filter( (conf: Config) => {
|
||||
const cluster = conf.getConfigArray("clusters").find( (val: Config) => {
|
||||
return val.getString("name") === name
|
||||
})
|
||||
if (cluster) {
|
||||
clusters.push(cluster)
|
||||
}
|
||||
})
|
||||
|
||||
if (clusters.length === 0 ) {
|
||||
throw new Error(`Cluster with name ${name} not found`)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue