From bda302df12856879fd78efad1569135b1706973b Mon Sep 17 00:00:00 2001 From: Max Audron Date: Sun, 16 May 2021 00:31:24 +0200 Subject: add deployment stuff --- .../jsonnet-libs/ksonnet-util/grafana.libsonnet | 71 ++++++ .../jsonnet-libs/ksonnet-util/k-compat.libsonnet | 22 ++ .../jsonnet-libs/ksonnet-util/kausal.libsonnet | 29 +++ .../ksonnet-util/legacy-custom.libsonnet | 156 ++++++++++++ .../ksonnet-util/legacy-noname.libsonnet | 51 ++++ .../ksonnet-util/legacy-subtypes.libsonnet | 168 +++++++++++++ .../ksonnet-util/legacy-types.libsonnet | 26 ++ .../jsonnet-libs/ksonnet-util/util.libsonnet | 264 +++++++++++++++++++++ 8 files changed, 787 insertions(+) create mode 100644 deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/grafana.libsonnet create mode 100644 deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/k-compat.libsonnet create mode 100644 deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet create mode 100644 deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-custom.libsonnet create mode 100644 deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-noname.libsonnet create mode 100644 deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-subtypes.libsonnet create mode 100644 deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-types.libsonnet create mode 100644 deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/util.libsonnet (limited to 'deploy/vendor/github.com/grafana/jsonnet-libs') diff --git a/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/grafana.libsonnet b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/grafana.libsonnet new file mode 100644 index 0000000..8277402 --- /dev/null +++ b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/grafana.libsonnet @@ -0,0 +1,71 @@ +// grafana.libsonnet provides the k-compat layer with grafana-opinionated defaults +(import 'k-compat.libsonnet') ++ { + core+: { + v1+: { + containerPort+:: { + // Force all ports to have names. + new(name, port):: + super.newNamed(name=name, containerPort=port), + + // Shortcut constructor for UDP ports. + newUDP(name, port):: + super.newNamedUDP(name=name, containerPort=port), + }, + + container+:: { + new(name, image):: + super.new(name, image) + + super.withImagePullPolicy('IfNotPresent'), + }, + }, + }, + + local appsExtentions = { + daemonSet+: { + new(name, containers, podLabels={}):: + super.new(name, containers, podLabels={}) + + + // Can't think of a reason we wouldn't want a DaemonSet to run on + // every node. + super.mixin.spec.template.spec.withTolerations([ + $.core.v1.toleration.new() + + $.core.v1.toleration.withOperator('Exists') + + $.core.v1.toleration.withEffect('NoSchedule'), + ]) + + + // We want to specify a minReadySeconds on every deamonset, so we get some + // very basic canarying, for instance, with bad arguments. + super.mixin.spec.withMinReadySeconds(10) + + super.mixin.spec.updateStrategy.withType('RollingUpdate'), + }, + + deployment+: { + new(name, replicas, containers, podLabels={}):: + super.new(name, replicas, containers, podLabels) + + + // We want to specify a minReadySeconds on every deployment, so we get some + // very basic canarying, for instance, with bad arguments. + super.mixin.spec.withMinReadySeconds(10) + + + // We want to add a sensible default for the number of old deployments + // handing around. + super.mixin.spec.withRevisionHistoryLimit(10), + }, + + statefulSet+: { + new(name, replicas, containers, volumeClaims=[], podLabels={}):: + super.new(name, replicas, containers, volumeClaims, podLabels) + + super.mixin.spec.updateStrategy.withType('RollingUpdate'), + }, + }, + + extensions+: { + v1beta1+: appsExtentions, + }, + + apps+: { + v1beta1+: appsExtentions, + v1+: appsExtentions, + }, +} diff --git a/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/k-compat.libsonnet b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/k-compat.libsonnet new file mode 100644 index 0000000..65b5b6e --- /dev/null +++ b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/k-compat.libsonnet @@ -0,0 +1,22 @@ +// k-compat.libsonnet provides a compatibility layer between k8s-alpha and ksonnet-lib. As ksonnet-lib has been +// abandoned, we consider it deprecated. This layer will generate a deprecation warning to those that still use it. +local k = import 'k.libsonnet'; + +k ++ ( + if std.objectHas(k, '__ksonnet') + then + std.trace( + 'Deprecated: ksonnet-lib has been abandoned, please consider using https://github.com/jsonnet-libs/k8s-alpha.', + (import 'legacy-types.libsonnet') + + (import 'legacy-custom.libsonnet') + + (import 'legacy-noname.libsonnet')({ + new(name=''):: super.new() + (if name != '' then super.mixin.metadata.withName(name) else {}), + }) + ) + else + (import 'legacy-subtypes.libsonnet') + + (import 'legacy-noname.libsonnet')({ + new(name=''):: super.new(name), + }) +) diff --git a/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet new file mode 100644 index 0000000..6a6f149 --- /dev/null +++ b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet @@ -0,0 +1,29 @@ +// kausal.libsonnet provides a backwards compatible way as many libraries leverage kausal.libsonnet. +// Ideally util.libsonnet is consumed separately. + +(import 'grafana.libsonnet') ++ { + local this = self, + _config+:: { + enable_rbac: true, + enable_pod_priorities: false, + namespace: error 'Must define a namespace', + }, + + util+:: + (import 'util.libsonnet').withK(this) + + { + rbac(name, rules):: + if $._config.enable_rbac + then super.rbac(name, rules, $._config.namespace) + else {}, + namespacedRBAC(name, rules):: + if $._config.enable_rbac + then super.namespacedRBAC(name, rules, $._config.namespace) + else {}, + podPriority(p): + if $._config.enable_pod_priorities + then super.podPriority(p) + else {}, + }, +} diff --git a/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-custom.libsonnet b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-custom.libsonnet new file mode 100644 index 0000000..e81e6a8 --- /dev/null +++ b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-custom.libsonnet @@ -0,0 +1,156 @@ +// legacy-custom.libsonnet retrofits k8s-alpha functionality into ksonnet-lib +{ + core+: { + v1+: { + configMap+: { + // allow configMap without data + new(name, data={}):: + super.new(name, data), + withData(data):: + // don't add 'data' key if data={} + if (data == {}) then {} + else super.withData(data), + withDataMixin(data):: + // don't add 'data' key if data={} + if (data == {}) then {} + else super.withDataMixin(data), + }, + + volume+:: { + // Make items parameter optional from fromConfigMap + fromConfigMap(name, configMapName, configMapItems=[]):: + { + configMap+: + if configMapItems == [] then { items:: null } + else {}, + } + + super.fromConfigMap(name, configMapName, configMapItems), + + // Shortcut constructor for secret volumes. + fromSecret(name, secretName):: + super.withName(name) + + super.mixin.secret.withSecretName(secretName), + + // Rename emptyDir to claimName + fromPersistentVolumeClaim(name='', claimName=''):: super.fromPersistentVolumeClaim(name=name, emptyDir=claimName), + }, + + volumeMount+:: { + // Override new, such that it doesn't always set readOnly: false. + new(name, mountPath, readOnly=false):: + {} + self.withName(name) + self.withMountPath(mountPath) + + if readOnly + then self.withReadOnly(readOnly) + else {}, + }, + + containerPort+:: { + // Shortcut constructor for UDP ports. + newNamedUDP(name, containerPort):: + super.newNamed(name=name, containerPort=containerPort) + + super.withProtocol('UDP'), + }, + + persistentVolumeClaim+:: { + new(name=''):: + super.new() + + (if name != '' + then super.mixin.metadata.withName(name) + else {}), + }, + + container+:: { + withEnvMixin(es):: + // if an envvar has an empty value ("") we want to remove that property + // because k8s will remove that and then it would always + // show up as a difference. + local removeEmptyValue(obj) = + if std.objectHas(obj, 'value') && std.length(obj.value) == 0 then + { + [k]: obj[k] + for k in std.objectFields(obj) + if k != 'value' + } + else + obj; + super.withEnvMixin([ + removeEmptyValue(envvar) + for envvar in es + ]), + + withEnvMap(es):: + self.withEnvMixin([ + $.core.v1.envVar.new(k, es[k]) + for k in std.objectFields(es) + ]), + }, + }, + }, + + batch+: { + v1beta1+: { + cronJob+: { + new(name='', schedule='', containers=[]):: + super.new() + + super.mixin.spec.jobTemplate.spec.template.spec.withContainers(containers) + + (if name != '' + then + super.mixin.metadata.withName(name) + + super.mixin.spec.jobTemplate.spec.template.metadata.withLabels({ name: name }) + else {}) + + ( + if schedule != '' + then super.mixin.spec.withSchedule(schedule) + else {} + ), + }, + }, + }, + + local appsExtentions = { + daemonSet+: { + new(name, containers, podLabels={}):: + local labels = podLabels { name: name }; + super.new() + + super.mixin.metadata.withName(name) + + super.mixin.spec.template.metadata.withLabels(labels) + + super.mixin.spec.template.spec.withContainers(containers) + + // apps.v1 requires an explicit selector: + super.mixin.spec.selector.withMatchLabels(labels), + }, + deployment+: { + new(name, replicas, containers, podLabels={}):: + local labels = podLabels { name: name }; + super.new(name, replicas, containers, labels) + + + // apps.v1 requires an explicit selector: + super.mixin.spec.selector.withMatchLabels(labels), + }, + statefulSet+: { + new(name, replicas, containers, volumeClaims=[], podLabels={}):: + local labels = podLabels { name: name }; + super.new(name, replicas, containers, volumeClaims, labels) + + + // apps.v1 requires an explicit selector: + super.mixin.spec.selector.withMatchLabels(labels) + + + // remove volumeClaimTemplates if empty + // (otherwise it will create a diff all the time) + ( + if std.length(volumeClaims) > 0 + then super.mixin.spec.withVolumeClaimTemplates(volumeClaims) + else {} + ), + }, + }, + + extensions+: { + v1beta1+: appsExtentions, + }, + + apps+: { + v1beta1+: appsExtentions, + v1+: appsExtentions, + }, + +} diff --git a/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-noname.libsonnet b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-noname.libsonnet new file mode 100644 index 0000000..388a10b --- /dev/null +++ b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-noname.libsonnet @@ -0,0 +1,51 @@ +// legacy-noname.libsonnet provides two-way compatibility, in k8s-alpha many new() functions have a mandatory name +// argument while they are absent in ksonnet-lib. `noNewEmptyNameMixin` allows us to make the argument optional in +// either situation. +function(noNewEmptyNameMixin) { + core+: { v1+: { + persistentVolumeClaim+: noNewEmptyNameMixin, + } }, + extensions+: { + v1beta1+: { + ingress+: noNewEmptyNameMixin, + }, + }, + networking+: { + v1beta1+: { + ingress+: noNewEmptyNameMixin, + }, + }, + batch+: { + v1+: { + job+: noNewEmptyNameMixin, + }, + v1beta1+: { + job+: noNewEmptyNameMixin, + }, + }, + local rbacPatch = { + role+: noNewEmptyNameMixin, + clusterRole+: noNewEmptyNameMixin, + roleBinding+: noNewEmptyNameMixin, + clusterRoleBinding+: noNewEmptyNameMixin, + }, + rbac+: { + v1+: rbacPatch, + v1beta1+: rbacPatch, + }, + policy+: { v1beta1+: { + podDisruptionBudget+: noNewEmptyNameMixin, + podSecurityPolicy+: noNewEmptyNameMixin, + } }, + storage+: { v1+: { + storageClass+: noNewEmptyNameMixin, + } }, + + scheduling+: { v1beta1+: { + priorityClass+: noNewEmptyNameMixin, + } }, + admissionregistration+: { v1beta1+: { + mutatingWebhookConfiguration+: noNewEmptyNameMixin, + validatingWebhookConfiguration+: noNewEmptyNameMixin, + } }, +} diff --git a/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-subtypes.libsonnet b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-subtypes.libsonnet new file mode 100644 index 0000000..0beddfc --- /dev/null +++ b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-subtypes.libsonnet @@ -0,0 +1,168 @@ +// legacy-subtypes.libsonnet makes first-class entities available as subtypes like in ksonnet-lib. +// It also makes the empty new() functions and camelCased functions available. +// This is largely based on kausal-shim.libsonnet from k8s-alpha. +{ + core+: { v1+: { + container+: { + envType: $.core.v1.envVar, + envFromType: $.core.v1.envFromSource, + portsType: $.core.v1.containerPort, + volumeMountsType: $.core.v1.volumeMount, + }, + pod+: { + spec+: { + volumesType: $.core.v1.volume, + }, + }, + service+: { + spec+: { + withClusterIp: self.withClusterIP, + withLoadBalancerIp: self.withLoadBalancerIP, + portsType: $.core.v1.servicePort, + }, + }, + + envFromSource+: { new():: {} }, + nodeSelector+: { new():: {} }, + nodeSelectorTerm+: { new():: {} }, + podAffinityTerm+: { new():: {} }, + preferredSchedulingTerm+: { new():: {} }, + toleration+: { new():: {} }, + localObjectReference+: { new():: {} }, + } }, + + local appsAffinityPatch = { + nodeAffinity+: { + requiredDuringSchedulingIgnoredDuringExecutionType: $.core.v1.nodeSelector { + nodeSelectorTermsType: $.core.v1.nodeSelectorTerm { + matchFieldsType: $.core.v1.nodeSelectorRequirement, + }, + }, + preferredDuringSchedulingIgnoredDuringExecutionType: $.core.v1.preferredSchedulingTerm { + preferenceType: { + matchFieldsType: $.core.v1.nodeSelectorRequirement, + }, + }, + }, + podAntiAffinity+: { + requiredDuringSchedulingIgnoredDuringExecutionType: $.core.v1.podAffinityTerm, + }, + }, + + local appsPatch = { + deployment+: { + spec+: { template+: { spec+: { + volumesType: $.core.v1.volume, + containersType: $.core.v1.container, + tolerationsType: $.core.v1.toleration, + affinity+: appsAffinityPatch, + } } }, + }, + daemonSet+: { + spec+: { template+: { spec+: { + withHostPid:: self.withHostPID, + tolerationsType: $.core.v1.toleration, + affinity+: appsAffinityPatch, + } } }, + }, + statefulSet+: { + spec+: { template+: { spec+: { + volumesType: $.core.v1.volume, + affinity+: appsAffinityPatch, + tolerationsType: $.core.v1.toleration, + imagePullSecretsType: $.core.v1.localObjectReference, + } } }, + }, + }, + + apps+: { + v1+: appsPatch, + v1beta1+: appsPatch, + }, + extensions+: { + v1beta1+: appsPatch { + ingress+: { + spec+: { + rulesType: $.extensions.v1beta1.ingressRule { + httpType+: { pathsType: $.extensions.v1beta1.httpIngressPath }, + }, + }, + }, + }, + }, + + batch+: { + local patch = { + mixin+: { spec+: { jobTemplate+: { spec+: { template+: { spec+: { + imagePullSecretsType: $.core.v1.localObjectReference, + } } } } } }, + }, + + v1+: { + job+: patch, + cronJob+: patch, + }, + v1beta1+: { + job+: patch, + cronJob+: patch, + }, + }, + + + local rbacPatch = { + local role = { + rulesType: $.rbac.v1beta1.policyRule, + }, + role+: role, + clusterRole+: role, + + local binding = { + subjectsType: $.rbac.v1beta1.subject, + }, + roleBinding+: binding, + clusterRoleBinding+: binding, + subject+: { new():: {} }, + + policyRule+: { + new():: {}, + withNonResourceUrls: self.withNonResourceURLs, + }, + }, + rbac+: { + v1+: rbacPatch, + v1beta1+: rbacPatch, + }, + + policy+: { + v1beta1+: { + idRange+: { new():: {} }, + podSecurityPolicy+: { + mixin+: { spec+: { + runAsUser+: { rangesType: $.policy.v1beta1.idRange }, + withHostIpc: self.withHostIPC, + withHostPid: self.withHostPID, + } }, + }, + }, + }, + + admissionregistration+: { v1beta1+: { + webhook+: { new():: {} }, + ruleWithOperations+: { new():: {} }, + local webhooksType = $.admissionregistration.v1beta1.webhook { + rulesType: $.admissionregistration.v1beta1.ruleWithOperations, + mixin+: { namespaceSelector+: { matchExpressionsType: { + new():: {}, + withKey(key):: { key: key }, + withOperator(operator):: { operator: operator }, + withValues(values):: { values: if std.isArray(values) then values else [values] }, + } } }, + }, + mutatingWebhookConfiguration+: { + webhooksType: webhooksType, + }, + validatingWebhookConfiguration+: { + webhooksType: webhooksType, + }, + } }, +} diff --git a/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-types.libsonnet b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-types.libsonnet new file mode 100644 index 0000000..b339021 --- /dev/null +++ b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/legacy-types.libsonnet @@ -0,0 +1,26 @@ +// legacy-types.libsonnet exposes hidden types from ksonnet-lib as first class citizens +// This list is likely to be incomplete. +{ + core+: { + v1+: { + container:: $.apps.v1.deployment.mixin.spec.template.spec.containersType, + containerPort:: $.core.v1.container.portsType, + envVar:: $.core.v1.container.envType, + envFromSource:: $.core.v1.container.envFromType, + servicePort:: $.core.v1.service.mixin.spec.portsType, + toleration:: $.apps.v1.deployment.mixin.spec.template.spec.tolerationsType, + volume:: $.core.v1.pod.mixin.spec.volumesType, + volumeMount:: $.core.v1.container.volumeMountsType, + }, + }, + rbac+: { + v1+: { + policyRule:: $.rbac.v1beta1.clusterRole.rulesType, + subject:: $.rbac.v1beta1.clusterRoleBinding.subjectsType, + }, + v1beta1+: { + policyRule:: $.rbac.v1beta1.clusterRole.rulesType, + subject:: $.rbac.v1beta1.clusterRoleBinding.subjectsType, + }, + }, +} diff --git a/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/util.libsonnet b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/util.libsonnet new file mode 100644 index 0000000..d97f7d5 --- /dev/null +++ b/deploy/vendor/github.com/grafana/jsonnet-libs/ksonnet-util/util.libsonnet @@ -0,0 +1,264 @@ +// util.libsonnet provides a number of useful (opinionated) shortcuts to replace boilerplate code + +local util(k) = { + // mapToFlags converts a map to a set of golang-style command line flags. + mapToFlags(map, prefix='-'): [ + '%s%s=%s' % [prefix, key, map[key]] + for key in std.objectFields(map) + if map[key] != null + ], + + // serviceFor create service for a given deployment. + serviceFor(deployment, ignored_labels=[], nameFormat='%(container)s-%(port)s'):: + local container = k.core.v1.container; + local service = k.core.v1.service; + local servicePort = k.core.v1.servicePort; + local ports = [ + servicePort.newNamed( + name=(nameFormat % { container: c.name, port: port.name }), + port=port.containerPort, + targetPort=port.containerPort + ) + + if std.objectHas(port, 'protocol') + then servicePort.withProtocol(port.protocol) + else {} + for c in deployment.spec.template.spec.containers + for port in (c + container.withPortsMixin([])).ports + ]; + local labels = { + [x]: deployment.spec.template.metadata.labels[x] + for x in std.objectFields(deployment.spec.template.metadata.labels) + if std.count(ignored_labels, x) == 0 + }; + + service.new( + deployment.metadata.name, // name + labels, // selector + ports, + ) + + service.mixin.metadata.withLabels({ name: deployment.metadata.name }), + + // rbac creates a service account, role and role binding with the given + // name and rules. + rbac(name, rules, namespace):: { + local clusterRole = k.rbac.v1.clusterRole, + local clusterRoleBinding = k.rbac.v1.clusterRoleBinding, + local subject = k.rbac.v1.subject, + local serviceAccount = k.core.v1.serviceAccount, + + service_account: + serviceAccount.new(name), + + cluster_role: + clusterRole.new() + + clusterRole.mixin.metadata.withName(name) + + clusterRole.withRules(rules), + + cluster_role_binding: + clusterRoleBinding.new() + + clusterRoleBinding.mixin.metadata.withName(name) + + clusterRoleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') + + clusterRoleBinding.mixin.roleRef.withKind('ClusterRole') + + clusterRoleBinding.mixin.roleRef.withName(name) + + clusterRoleBinding.withSubjects([ + subject.new() + + subject.withKind('ServiceAccount') + + subject.withName(name) + + subject.withNamespace(namespace), + ]), + }, + + namespacedRBAC(name, rules, namespace):: { + local role = k.rbac.v1.role, + local roleBinding = k.rbac.v1.roleBinding, + local subject = k.rbac.v1.subject, + local serviceAccount = k.core.v1.serviceAccount, + + service_account: + serviceAccount.new(name) + + serviceAccount.mixin.metadata.withNamespace(namespace), + + role: + role.new() + + role.mixin.metadata.withName(name) + + role.mixin.metadata.withNamespace(namespace) + + role.withRules(rules), + + role_binding: + roleBinding.new() + + roleBinding.mixin.metadata.withName(name) + + roleBinding.mixin.metadata.withNamespace(namespace) + + roleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') + + roleBinding.mixin.roleRef.withKind('Role') + + roleBinding.mixin.roleRef.withName(name) + + roleBinding.withSubjects([ + subject.new() + + subject.withKind('ServiceAccount') + + subject.withName(name) + + subject.withNamespace(namespace), + ]), + }, + + // VolumeMount helper functions can be augmented with mixins. + // For example, passing "volumeMount.withSubPath(subpath)" will result in + // a subpath mixin. + configVolumeMount(name, path, volumeMountMixin={}):: + local container = k.core.v1.container, + deployment = k.apps.v1.deployment, + volumeMount = k.core.v1.volumeMount, + volume = k.core.v1.volume, + addMount(c) = c + container.withVolumeMountsMixin( + volumeMount.new(name, path) + + volumeMountMixin, + ); + + deployment.mapContainers(addMount) + + deployment.mixin.spec.template.spec.withVolumesMixin([ + volume.fromConfigMap(name, name), + ]), + + // configMapVolumeMount adds a configMap to deployment-like objects. + // It will also add an annotation hash to ensure the pods are re-deployed + // when the config map changes. + configMapVolumeMount(configMap, path, volumeMountMixin={}):: + local name = configMap.metadata.name, + hash = std.md5(std.toString(configMap)), + container = k.core.v1.container, + deployment = k.apps.v1.deployment, + volumeMount = k.core.v1.volumeMount, + volume = k.core.v1.volume, + addMount(c) = c + container.withVolumeMountsMixin( + volumeMount.new(name, path) + + volumeMountMixin, + ); + + deployment.mapContainers(addMount) + + deployment.mixin.spec.template.spec.withVolumesMixin([ + volume.fromConfigMap(name, name), + ]) + + deployment.mixin.spec.template.metadata.withAnnotationsMixin({ + ['%s-hash' % name]: hash, + }), + + hostVolumeMount(name, hostPath, path, readOnly=false, volumeMountMixin={}):: + local container = k.core.v1.container, + deployment = k.apps.v1.deployment, + volumeMount = k.core.v1.volumeMount, + volume = k.core.v1.volume, + addMount(c) = c + container.withVolumeMountsMixin( + volumeMount.new(name, path, readOnly=readOnly) + + volumeMountMixin, + ); + + deployment.mapContainers(addMount) + + deployment.mixin.spec.template.spec.withVolumesMixin([ + volume.fromHostPath(name, hostPath), + ]), + + pvcVolumeMount(pvcName, path, readOnly=false, volumeMountMixin={}):: + local container = k.core.v1.container, + deployment = k.apps.v1.deployment, + volumeMount = k.core.v1.volumeMount, + volume = k.core.v1.volume, + addMount(c) = c + container.withVolumeMountsMixin( + volumeMount.new(pvcName, path, readOnly=readOnly) + + volumeMountMixin, + ); + + deployment.mapContainers(addMount) + + deployment.mixin.spec.template.spec.withVolumesMixin([ + volume.fromPersistentVolumeClaim(pvcName, pvcName), + ]), + + secretVolumeMount(name, path, defaultMode=256, volumeMountMixin={}):: + local container = k.core.v1.container, + deployment = k.apps.v1.deployment, + volumeMount = k.core.v1.volumeMount, + volume = k.core.v1.volume, + addMount(c) = c + container.withVolumeMountsMixin( + volumeMount.new(name, path) + + volumeMountMixin, + ); + + deployment.mapContainers(addMount) + + deployment.mixin.spec.template.spec.withVolumesMixin([ + volume.fromSecret(name, secretName=name) + + volume.mixin.secret.withDefaultMode(defaultMode), + ]), + + emptyVolumeMount(name, path, volumeMountMixin={}, volumeMixin={}):: + local container = k.core.v1.container, + deployment = k.apps.v1.deployment, + volumeMount = k.core.v1.volumeMount, + volume = k.core.v1.volume, + addMount(c) = c + container.withVolumeMountsMixin( + volumeMount.new(name, path) + + volumeMountMixin, + ); + + deployment.mapContainers(addMount) + + deployment.mixin.spec.template.spec.withVolumesMixin([ + volume.fromEmptyDir(name) + volumeMixin, + ]), + + manifestYaml(value):: ( + local f = std.native('manifestYamlFromJson'); + f(std.toString(value)) + ), + + resourcesRequests(cpu, memory):: + k.core.v1.container.mixin.resources.withRequests( + (if cpu != null + then { cpu: cpu } + else {}) + + (if memory != null + then { memory: memory } + else {}) + ), + + resourcesLimits(cpu, memory):: + k.core.v1.container.mixin.resources.withLimits( + (if cpu != null + then { cpu: cpu } + else {}) + + (if memory != null + then { memory: memory } + else {}) + ), + + antiAffinity: + { + local deployment = k.apps.v1.deployment, + local podAntiAffinity = deployment.mixin.spec.template.spec.affinity.podAntiAffinity, + local name = super.spec.template.metadata.labels.name, + + spec+: podAntiAffinity.withRequiredDuringSchedulingIgnoredDuringExecution([ + podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecutionType.new() + + podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecutionType.mixin.labelSelector.withMatchLabels({ name: name }) + + podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecutionType.withTopologyKey('kubernetes.io/hostname'), + ]).spec, + }, + + antiAffinityStatefulSet: + { + local statefulSet = k.apps.v1.statefulSet, + local podAntiAffinity = statefulSet.mixin.spec.template.spec.affinity.podAntiAffinity, + local name = super.spec.template.metadata.labels.name, + + spec+: podAntiAffinity.withRequiredDuringSchedulingIgnoredDuringExecution([ + podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecutionType.new() + + podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecutionType.mixin.labelSelector.withMatchLabels({ name: name }) + + podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecutionType.withTopologyKey('kubernetes.io/hostname'), + ]).spec, + }, + + // Add a priority to the pods in a deployment (or deployment-like objects + // such as a statefulset). + local deployment = k.apps.v1.deployment, + podPriority(p): + deployment.mixin.spec.template.spec.withPriorityClassName(p), +}; + +util((import 'grafana.libsonnet')) + { + withK(k):: util(k), +} -- cgit v1.2.3