/* * Copyright © 2020 Atomist, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as k8s from "@pulumi/kubernetes"; import * as pulumi from "@pulumi/pulumi"; import { MinimalK8sSpec, specResourceName } from "./spec"; /** Arguments for [[deployK8sSdm]]. */ export interface DeployK8sSdmArgs { /** Atomist API key */ apiKey: pulumi.Output; /** Simple cluster name */ clusterName: string; /** Kubernetes provider */ provider: k8s.Provider; /** Atomist workspace IDs */ workspaceIds: string[]; /** Optional k8s-sdm version */ k8sSdmVersion?: string; /** * Options to use when creating the resources. The Kubernetes * provider will be automatically set as the provider. */ options?: pulumi.CustomResourceOptions; /** Optional k8s-sdm sync options */ sync?: { repo: { owner: string; repo: string; branch?: string; }; intervalMinutes?: number; secretKey?: string; specFormat?: "json" | "yaml"; }; /** Transformations for the pulumi k8s.yaml.ConfigFile constructor. */ transformations?: Array< (o: any, opts: pulumi.CustomResourceOptions) => void >; } /** * Deploy k8s-sdm. */ export function deployK8sSdm( args: DeployK8sSdmArgs, ): pulumi.Output<{ [key: string]: pulumi.CustomResource }> { const k8sSdm = "k8s-sdm"; const k8sOpts = { ...args.options, provider: args.provider }; const k8sSdmSpecsUrl = `https://raw.githubusercontent.com/atomist/${k8sSdm}/main/assets/kubectl/sync.yaml`; const configFile = new k8s.yaml.ConfigFile( k8sSdm, { file: k8sSdmSpecsUrl, transformations: [ (spec: any) => { if (spec.kind === "Deployment" && args.k8sSdmVersion) { spec.spec.template.spec.containers[0].image = `atomist/${k8sSdm}:${args.k8sSdmVersion}`; } }, ...(args.transformations || []), ], }, k8sOpts, ); const resources = configFile.resources; const sync = args.sync; if (sync && sync.repo) { sync.repo.branch = sync.repo.branch || "main"; sync.intervalMinutes = sync.intervalMinutes || 10; sync.specFormat = sync.specFormat || "json"; } const secretSpec: k8s.core.v1.SecretArgs & MinimalK8sSpec = { apiVersion: "v1" as const, data: { "client.config.json": pulumi.all([args.apiKey]).apply(([apiKey]) => Buffer.from( JSON.stringify({ apiKey: apiKey, environment: args.clusterName, name: `@atomist/k8s-sdm_${args.clusterName}`, policy: "ephemeral", sdm: { k8s: { options: { sync, }, }, }, workspaceIds: args.workspaceIds, }), ).toString("base64"), ), }, kind: "Secret" as const, metadata: { name: k8sSdm, namespace: "sdm", }, type: "Opaque" as const, }; const secretResourceName = specResourceName(secretSpec); if (!secretResourceName) { throw new Error(`Failed to create resource name for secret spec`); } const k8sSdmSecret = new k8s.core.v1.Secret( secretResourceName, secretSpec, { ...k8sOpts, dependsOn: resources.apply(rs => Object.values(rs)) }, ); resources[secretResourceName] = pulumi.output(k8sSdmSecret); return resources; }