UNPKG

@atomist/sdm

Version:

Atomist Software Delivery Machine SDK

135 lines 5.12 kB
"use strict"; /* * 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.labelMatch = exports.applicationLabels = exports.labelSelector = exports.matchLabels = exports.safeLabelValue = void 0; /** * Remove objectionable characters from a Kubernetes label value. * The validation regular expression for a label value is * /^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$/. * * @param value The label value * @return A valid label value based on the input */ function safeLabelValue(value) { return value.replace(/^[^A-Za-z0-9]+/, "") .replace(/[^A-Za-z0-9]+$/, "") .replace(/[^-A-Za-z0-9_.]+/g, "_"); } exports.safeLabelValue = safeLabelValue; /** * Returns the subset of the default set of labels for that should be * used in a matchLabels to match a resource. * * @param req A Kubernetes request object containing at least the "name" and "workspaceId" properties * @return Kubernetes object metadata labels object */ function matchLabels(req) { return { "app.kubernetes.io/name": req.name, "atomist.com/workspaceId": req.workspaceId, }; } exports.matchLabels = matchLabels; /** * Provide label selector string suitable for passing to a Kubernetes * API call for the provided `req` object. * * @param req A Kubernetes request object containing at least the "name" and "workspaceId" properties * @return Kubernetes label selector string */ function labelSelector(req) { const matchers = matchLabels(req); return Object.keys(matchers).map(l => `${l}=${matchers[l]}`).join(","); } exports.labelSelector = labelSelector; /** * Create a default set of labels for a resource. The returned set * satisfy the recommendations from * https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ */ function applicationLabels(req) { const matchers = matchLabels(req); const labels = Object.assign(Object.assign({}, matchers), { "app.kubernetes.io/part-of": req.name, "app.kubernetes.io/managed-by": safeLabelValue(req.sdmFulfiller) }); if (req.component) { labels["app.kubernetes.io/component"] = req.component; } if (req.instance) { labels["app.kubernetes.io/instance"] = req.instance; } if (req.version) { labels["app.kubernetes.io/version"] = req.version; } return labels; } exports.applicationLabels = applicationLabels; /** * Determine if labels match selector. If the selector contains no * label selector, it is considered a match. If the the matchLabels * contain no properties, it is considered matching. If the * matchExpressions array is empty, it is considered matching. * * @param spec Kubernetes object spec * @param selector Kubernetes label selector * @return Return `true` if it is a match, `false` otherwise */ function labelMatch(spec, selector) { if (!selector) { return true; } if (!spec.metadata || !spec.metadata.labels) { return false; } if (selector.matchLabels) { for (const label of Object.keys(selector.matchLabels)) { if (!spec.metadata.labels.hasOwnProperty(label) || spec.metadata.labels[label] !== selector.matchLabels[label]) { return false; } } } if (selector.matchExpressions) { for (const expr of selector.matchExpressions) { switch (expr.operator) { case "Exists": if (!spec.metadata.labels.hasOwnProperty(expr.key)) { return false; } break; case "DoesNotExist": if (spec.metadata.labels.hasOwnProperty(expr.key)) { return false; } break; case "In": if (!spec.metadata.labels.hasOwnProperty(expr.key) || !expr.values.includes(spec.metadata.labels[expr.key])) { return false; } break; case "NotIn": if (spec.metadata.labels.hasOwnProperty(expr.key) && expr.values.includes(spec.metadata.labels[expr.key])) { return false; } break; default: throw new Error(`Unsupported match expression operator: ${expr.operator}`); break; } } } return true; } exports.labelMatch = labelMatch; //# sourceMappingURL=labels.js.map