diff --git a/dist/index.js b/dist/index.js index c1e228f9..0e9a74c2 100644 Binary files a/dist/index.js and b/dist/index.js differ diff --git a/dist/index.js.map b/dist/index.js.map index 5766303f..8f752321 100644 Binary files a/dist/index.js.map and b/dist/index.js.map differ diff --git a/src/model/cloud-runner/providers/k8s/index.ts b/src/model/cloud-runner/providers/k8s/index.ts index 048a69b8..e4eb70dc 100644 --- a/src/model/cloud-runner/providers/k8s/index.ts +++ b/src/model/cloud-runner/providers/k8s/index.ts @@ -15,6 +15,7 @@ import CloudRunner from '../../cloud-runner'; import { ProviderResource } from '../provider-resource'; import { ProviderWorkflow } from '../provider-workflow'; import { RemoteClientLogger } from '../../remote-client/remote-client-logger'; +import { KubernetesRole } from './kubernetes-role'; class Kubernetes implements ProviderInterface { public static Instance: Kubernetes; @@ -244,6 +245,7 @@ class Kubernetes implements ProviderInterface { this.containerName, ); await new Promise((promise) => setTimeout(promise, 15000)); + await KubernetesRole.createRole(this.serviceAccountName, this.namespace); const result = await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec); CloudRunnerLogger.log(`Build job created`); await new Promise((promise) => setTimeout(promise, 5000)); @@ -267,6 +269,7 @@ class Kubernetes implements ProviderInterface { try { await this.kubeClientBatch.deleteNamespacedJob(this.jobName, this.namespace); await this.kubeClient.deleteNamespacedPod(this.podName, this.namespace); + await KubernetesRole.deleteRole(this.serviceAccountName, this.namespace); } catch (error: any) { CloudRunnerLogger.log(`Failed to cleanup`); if (error.response.body.reason !== `NotFound`) { diff --git a/src/model/cloud-runner/providers/k8s/kubernetes-role.ts b/src/model/cloud-runner/providers/k8s/kubernetes-role.ts new file mode 100644 index 00000000..09a26d06 --- /dev/null +++ b/src/model/cloud-runner/providers/k8s/kubernetes-role.ts @@ -0,0 +1,56 @@ +import { RbacAuthorizationV1Api } from '@kubernetes/client-node'; + +class KubernetesRole { + static async createRole(serviceAccountName: string, namespace: string) { + const rbac = new RbacAuthorizationV1Api(); + + // create admin kubernetes role and role binding + const roleBinding = { + apiVersion: 'rbac.authorization.k8s.io/v1', + kind: 'RoleBinding', + metadata: { + name: `${serviceAccountName}-admin`, + namespace, + }, + subjects: [ + { + kind: 'ServiceAccount', + name: serviceAccountName, + namespace, + }, + ], + roleRef: { + apiGroup: 'rbac.authorization.k8s.io', + kind: 'Role', + name: `${serviceAccountName}-admin`, + }, + }; + + const role = { + apiVersion: 'rbac.authorization.k8s.io/v1', + kind: 'Role', + metadata: { + name: `${serviceAccountName}-admin`, + namespace, + }, + rules: [ + { + apiGroups: ['*'], + resources: ['*'], + verbs: ['*'], + }, + ], + }; + const roleBindingResponse = await rbac.createNamespacedRoleBinding(namespace, roleBinding); + const roleResponse = await rbac.createNamespacedRole(namespace, role); + + return { roleBindingResponse, roleResponse }; + } + + public static async deleteRole(serviceAccountName: string, namespace: string) { + const rbac = new RbacAuthorizationV1Api(); + await rbac.deleteNamespacedRoleBinding(`${serviceAccountName}-admin`, namespace); + await rbac.deleteNamespacedRole(`${serviceAccountName}-admin`, namespace); + } +} +export { KubernetesRole };