@adpt/cloud
Version:
AdaptJS cloud component library
149 lines • 5.78 kB
JavaScript
;
/*
* Copyright 2018-2019 Unbounded Systems, LLC
*
* 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 });
const tslib_1 = require("tslib");
const core_1 = tslib_1.__importStar(require("@adpt/core"));
const utils_1 = require("@adpt/utils");
const lodash_1 = tslib_1.__importDefault(require("lodash"));
const common_1 = require("./common");
const Container_1 = require("./Container");
const k8s_observer_1 = require("./k8s_observer");
const manifest_support_1 = require("./manifest_support");
const Resource_1 = require("./Resource");
function isContainerArray(children) {
const badKids = children.filter((c) => !core_1.isElement(c) || !Container_1.isK8sContainerElement(c));
if (badKids.length === 0)
return true;
const names = badKids.map((c) => core_1.isElement(c) ? c.componentName : String(c));
throw new core_1.BuildNotImplemented(`Pod children must be of type ` +
`${Container_1.K8sContainer.name}. Invalid children are: ${names.join(", ")}`);
}
function dups(data) {
const grouped = lodash_1.default.groupBy(data, lodash_1.default.identity);
const filtered = lodash_1.default.filter(grouped, (val) => val.length > 1);
return lodash_1.default.uniq(lodash_1.default.flatten(filtered));
}
function defaultize(spec) {
spec = Object.assign({}, spec);
if (spec.env && spec.env.length === 0)
delete spec.env;
if (spec.tty !== true)
delete spec.tty;
if (spec.ports && spec.ports.length === 0)
delete spec.ports;
if (spec.ports) {
spec.ports = spec.ports.map((p) => p.protocol ? p : Object.assign({}, p, { protocol: "TCP" }));
}
return spec;
}
function makePodManifest(props) {
const containers = lodash_1.default.compact(core_1.childrenToArray(props.children)
.map((c) => Container_1.isK8sContainerElement(c) ? c : null));
const spec = {
containers: containers.map((c) => ({
args: c.props.args,
command: c.props.command,
env: c.props.env,
image: c.props.image,
imagePullPolicy: c.props.imagePullPolicy,
name: c.props.name,
ports: c.props.ports,
tty: c.props.tty,
workingDir: c.props.workingDir,
}))
.map(defaultize)
.map(utils_1.removeUndef),
terminationGracePeriodSeconds: props.terminationGracePeriodSeconds
};
return {
kind: "Pod",
metadata: {},
spec,
};
}
/**
* Component for Kubernetes Pods
*
* @public
*/
class Pod extends core_1.DeferredComponent {
build() {
const { key } = this.props;
if (!key)
throw new utils_1.InternalError("key is null");
const children = core_1.childrenToArray(this.props.children);
if (lodash_1.default.isEmpty(children))
return null;
if (!isContainerArray(children))
return null;
const containerNames = children.map((child) => child.props.name);
const dupNames = dups(containerNames);
if (!lodash_1.default.isEmpty(dupNames)) {
throw new core_1.BuildNotImplemented(`Duplicate names within a pod: ${dupNames.join(", ")}`);
}
const manifest = makePodManifest(this.props);
return (core_1.default.createElement(Resource_1.Resource, { key: key, config: this.props.config, kind: "Pod", metadata: manifest.metadata, spec: manifest.spec }));
}
async status(_observe, buildData) {
const succ = buildData.successor;
if (!succ)
return undefined;
return succ.status();
}
}
Pod.defaultProps = {
terminationGracePeriodSeconds: 30,
};
exports.Pod = Pod;
function deployedWhen(statusObj) {
const status = statusObj;
if (!status || !status.status)
return core_1.waiting(`Kubernetes cluster returned invalid status for Pod`);
if (status.status.phase === "Running")
return true;
let msg = `Pod state ${status.status.phase}`;
if (Array.isArray(status.status.conditions)) {
const failing = status.status.conditions
.filter((cond) => cond.status !== "True")
.map((cond) => cond.message)
.join("; ");
if (failing)
msg += `: ${failing}`;
}
return core_1.waiting(msg);
}
/** @internal */
exports.podResourceInfo = {
kind: "Pod",
apiName: "pods",
deployedWhen,
statusQuery: async (props, observe, buildData) => {
const obs = await observe(k8s_observer_1.K8sObserver, core_1.gql `
query ($name: String!, $kubeconfig: JSON!, $namespace: String!) {
withKubeconfig(kubeconfig: $kubeconfig) {
readCoreV1NamespacedPod(name: $name, namespace: $namespace) @all(depth: 100)
}
}`, {
name: manifest_support_1.resourceIdToName(props.key, buildData.id, buildData.deployID),
kubeconfig: props.config.kubeconfig,
namespace: common_1.computeNamespaceFromMetadata(props.metadata)
});
return obs.withKubeconfig.readCoreV1NamespacedPod;
},
};
manifest_support_1.registerResourceKind(exports.podResourceInfo);
//# sourceMappingURL=Pod.js.map