@atomist/sdm
Version:
Atomist Software Delivery Machine SDK
145 lines • 5.36 kB
JavaScript
;
/*
* 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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.deploymentTemplate = exports.upsertDeployment = void 0;
const logger_1 = require("@atomist/automation-client/lib/util/logger");
const _ = require("lodash");
const error_1 = require("../support/error");
const retry_1 = require("../support/retry");
const labels_1 = require("./labels");
const metadata_1 = require("./metadata");
const patch_1 = require("./patch");
const request_1 = require("./request");
const resource_1 = require("./resource");
/**
* Create or update a deployment for a Kubernetes application. Any
* provided `req.deploymentSpec` is merged using
* [[deploymentTemplate]] before creating/patching.
*
* @param req Kuberenetes application request
* @return Kubernetes spec used to create/update resource
*/
async function upsertDeployment(req) {
const slug = request_1.appName(req);
const spec = await deploymentTemplate(req);
try {
await req.clients.apps.readNamespacedDeployment(spec.metadata.name, spec.metadata.namespace);
}
catch (e) {
logger_1.logger.debug(`Failed to read deployment ${slug}, creating: ${error_1.k8sErrMsg(e)}`);
logger_1.logger.info(`Creating deployment ${slug} using '${resource_1.logObject(spec)}'`);
await retry_1.logRetry(() => req.clients.apps.createNamespacedDeployment(spec.metadata.namespace, spec), `create deployment ${slug}`);
return spec;
}
logger_1.logger.info(`Updating deployment ${slug} using '${resource_1.logObject(spec)}'`);
await retry_1.logRetry(() => req.clients.apps.patchNamespacedDeployment(spec.metadata.name, spec.metadata.namespace, spec, undefined, undefined, undefined, undefined, patch_1.patchHeaders(req)), `patch deployment ${slug}`);
return spec;
}
exports.upsertDeployment = upsertDeployment;
/**
* Create deployment spec for a Kubernetes application. If the
* request has a `deploymentSpec`, it is merged into the default spec
* created by this function using `lodash.merge(default, req.deploymentSpec)`.
*
* It is possible to override the deployment name using the
* [[KubernetesApplication.deploymentSpec]]. If you do this, make
* sure you know what you are doing.
*
* @param req Kubernetes application request
* @return deployment resource specification
*/
async function deploymentTemplate(req) {
const labels = labels_1.applicationLabels(req);
const matchers = labels_1.matchLabels(req);
const metadata = metadata_1.metadataTemplate({
name: req.name,
namespace: req.ns,
labels,
});
const podMetadata = metadata_1.metadataTemplate({
name: req.name,
labels,
});
const selector = {
matchLabels: matchers,
};
const apiVersion = "apps/v1";
const kind = "Deployment";
const d = {
apiVersion,
kind,
metadata,
spec: {
selector,
strategy: {
type: "RollingUpdate",
rollingUpdate: {
maxUnavailable: 0,
maxSurge: 1,
},
},
template: {
metadata: podMetadata,
spec: {
containers: [
{
image: req.image,
name: req.name,
resources: {
limits: {
cpu: "1000m",
memory: "384Mi",
},
requests: {
cpu: "100m",
memory: "320Mi",
},
},
},
],
},
},
},
};
if (req.port) {
d.spec.template.spec.containers[0].ports = [
{
name: "http",
containerPort: req.port,
},
];
const probe = {
httpGet: {
path: "/",
port: "http",
},
initialDelaySeconds: 30,
};
d.spec.template.spec.containers[0].readinessProbe = probe;
d.spec.template.spec.containers[0].livenessProbe = probe;
}
if (req.roleSpec) {
d.spec.template.spec.serviceAccountName = _.get(req, "serviceAccountSpec.metadata.name", req.name);
}
if (req.deploymentSpec) {
_.merge(d, req.deploymentSpec, { apiVersion, kind });
d.metadata.namespace = req.ns;
}
return d;
}
exports.deploymentTemplate = deploymentTemplate;
//# sourceMappingURL=deployment.js.map