2019-09-27 00:02:33 +02:00
|
|
|
local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet';
|
|
|
|
|
|
|
|
{
|
2019-10-09 22:11:17 +02:00
|
|
|
// Generates the manifests for all objects in kp except those starting with "_"
|
|
|
|
generate(kp):: (
|
|
|
|
{
|
|
|
|
[std.asciiLower(module) + '-' + name]: kp[module][name]
|
2020-03-18 22:01:01 +01:00
|
|
|
for module in std.objectFieldsAll(kp)
|
|
|
|
if !std.startsWith(module, '_')
|
2019-10-09 22:11:17 +02:00
|
|
|
for name in std.objectFields(kp[module])
|
|
|
|
}
|
|
|
|
),
|
|
|
|
|
2019-09-27 00:02:33 +02:00
|
|
|
// Join multiple objects into one
|
|
|
|
join_objects(objs)::
|
|
|
|
local aux(arr, i, running) =
|
|
|
|
if i >= std.length(arr) then
|
|
|
|
running
|
|
|
|
else
|
|
|
|
aux(arr, i + 1, running + arr[i]) tailstrict;
|
|
|
|
aux(objs, 0, {}),
|
|
|
|
|
2019-10-09 22:11:17 +02:00
|
|
|
// Creates serviceaccount
|
|
|
|
newServiceAccount(name, namespace, labels):: (
|
2020-03-18 22:01:01 +01:00
|
|
|
local serviceAccount = k.core.v1.serviceAccount;
|
2019-10-09 22:11:17 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
serviceAccount.new(name)
|
|
|
|
+ (if labels != null then serviceAccount.mixin.metadata.withLabels(labels) else {})
|
|
|
|
+ serviceAccount.mixin.metadata.withNamespace(namespace)
|
2019-10-09 22:11:17 +02:00
|
|
|
),
|
|
|
|
|
2019-10-09 16:52:00 +02:00
|
|
|
// Creates ClusterRoles
|
2019-10-09 22:11:17 +02:00
|
|
|
// roles format example: [{apis: ['authentication.k8s.io'],
|
2019-10-09 16:52:00 +02:00
|
|
|
// res: ['tokenreviews'],
|
|
|
|
// verbs: ['create']
|
2019-10-09 22:11:17 +02:00
|
|
|
// },[{...}]]
|
2020-03-18 22:01:01 +01:00
|
|
|
newClusterRole(name, roles, labels):: (
|
|
|
|
local clusterRole = k.rbac.v1.clusterRole;
|
|
|
|
local policyRule = clusterRole.rulesType;
|
2019-10-09 16:52:00 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
local p(apigroups, resources, verbs) = policyRule.new()
|
|
|
|
+ policyRule.withApiGroups([a for a in apigroups])
|
|
|
|
+ policyRule.withResources([r for r in resources])
|
|
|
|
+ policyRule.withVerbs([v for v in verbs]);
|
2019-10-09 16:52:00 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
local r = [p(pol.apis, pol.res, pol.verbs) for pol in roles];
|
2019-10-09 16:52:00 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
local rules = r;
|
2019-10-09 16:52:00 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
local c = clusterRole.new()
|
|
|
|
+ (if labels != null then clusterRole.mixin.metadata.withLabels(labels) else {})
|
|
|
|
+ clusterRole.mixin.metadata.withName(name)
|
|
|
|
+ clusterRole.withRules(rules);
|
|
|
|
c
|
|
|
|
),
|
2019-10-09 16:52:00 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
// Creates a ClusterRoleBinding between a `clusterRole` and a `serviceAccount` on `serviceAccountNamespace`
|
|
|
|
newClusterRoleBinding(name, serviceAccount, serviceAccountNamespace, clusterRole, labels):: (
|
|
|
|
local clusterRoleBinding = k.rbac.v1.clusterRoleBinding;
|
2019-10-09 22:11:17 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
clusterRoleBinding.new()
|
|
|
|
+ clusterRoleBinding.mixin.metadata.withName(name)
|
|
|
|
+ (if labels != null then clusterRoleBinding.mixin.metadata.withLabels(labels) else {})
|
|
|
|
+ clusterRoleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io')
|
|
|
|
+ clusterRoleBinding.mixin.roleRef.withName(clusterRole)
|
|
|
|
+ clusterRoleBinding.mixin.roleRef.mixinInstance({ kind: 'ClusterRole' })
|
|
|
|
+ clusterRoleBinding.withSubjects([{ kind: 'ServiceAccount', name: serviceAccount, namespace: serviceAccountNamespace }])
|
|
|
|
),
|
2019-10-09 22:11:17 +02:00
|
|
|
|
2019-09-27 00:02:33 +02:00
|
|
|
// Creates endpoint objects
|
|
|
|
newEndpoint(name, namespace, ips, portName, portNumber):: (
|
|
|
|
local endpoints = k.core.v1.endpoints;
|
|
|
|
local endpointSubset = endpoints.subsetsType;
|
|
|
|
local endpointPort = endpointSubset.portsType;
|
2019-10-11 22:15:14 +02:00
|
|
|
local Port = endpointPort.new()
|
2020-03-18 22:01:01 +01:00
|
|
|
+ endpointPort.withName(portName)
|
|
|
|
+ endpointPort.withPort(portNumber)
|
|
|
|
+ endpointPort.withProtocol('TCP');
|
2019-09-27 00:02:33 +02:00
|
|
|
|
2019-10-11 22:15:14 +02:00
|
|
|
local subset = endpointSubset.new()
|
2020-03-18 22:01:01 +01:00
|
|
|
+ endpointSubset.withAddresses([
|
|
|
|
{ ip: IP }
|
|
|
|
for IP in ips
|
|
|
|
])
|
|
|
|
+ endpointSubset.withPorts(Port);
|
2019-10-11 22:15:14 +02:00
|
|
|
endpoints.new()
|
2020-03-18 22:01:01 +01:00
|
|
|
+ endpoints.mixin.metadata.withName(name)
|
|
|
|
+ endpoints.mixin.metadata.withNamespace(namespace)
|
|
|
|
+ endpoints.mixin.metadata.withLabels({ 'k8s-app': name })
|
|
|
|
+ endpoints.withSubsets(subset)
|
|
|
|
),
|
2019-09-27 00:02:33 +02:00
|
|
|
|
|
|
|
// Creates ingress objects
|
|
|
|
newIngress(name, namespace, host, path, serviceName, servicePort):: (
|
|
|
|
local ingress = k.extensions.v1beta1.ingress;
|
|
|
|
local ingressTls = ingress.mixin.spec.tlsType;
|
|
|
|
local ingressRule = ingress.mixin.spec.rulesType;
|
|
|
|
local httpIngressPath = ingressRule.mixin.http.pathsType;
|
|
|
|
|
2019-10-11 22:15:14 +02:00
|
|
|
ingress.new()
|
|
|
|
+ ingress.mixin.metadata.withName(name)
|
|
|
|
+ ingress.mixin.metadata.withNamespace(namespace)
|
|
|
|
+ ingress.mixin.spec.withRules(
|
|
|
|
ingressRule.new()
|
|
|
|
+ ingressRule.withHost(host)
|
|
|
|
+ ingressRule.mixin.http.withPaths(
|
|
|
|
httpIngressPath.new()
|
|
|
|
+ httpIngressPath.withPath(path)
|
|
|
|
+ httpIngressPath.mixin.backend.withServiceName(serviceName)
|
|
|
|
+ httpIngressPath.mixin.backend.withServicePort(servicePort)
|
2019-09-27 00:02:33 +02:00
|
|
|
),
|
|
|
|
)
|
|
|
|
),
|
|
|
|
|
2020-03-02 20:46:38 +01:00
|
|
|
// Add TLS to Ingress resource with secret containing the certificates if exists
|
|
|
|
addIngressTLS(I, S=''):: (
|
|
|
|
local ingress = k.extensions.v1beta1.ingress;
|
|
|
|
local ingressTls = ingress.mixin.spec.tlsType;
|
|
|
|
local host = I.spec.rules[0].host;
|
|
|
|
local namespace = I.metadata.namespace;
|
|
|
|
|
|
|
|
I + ingress.mixin.spec.withTls(
|
|
|
|
ingressTls.new() +
|
2020-03-18 22:01:01 +01:00
|
|
|
ingressTls.withHosts(host) +
|
|
|
|
(if S != '' then { secretName: S } else {})
|
2020-03-02 20:46:38 +01:00
|
|
|
)
|
|
|
|
),
|
|
|
|
|
|
|
|
// Creates a new TLS Secred with Certificate and Key
|
|
|
|
newTLSSecret(name, namespace, crt, key):: (
|
|
|
|
local secret = k.core.v1.secret;
|
|
|
|
|
2020-06-15 23:28:46 +02:00
|
|
|
secret.new(name) +
|
2020-03-18 22:01:01 +01:00
|
|
|
secret.mixin.metadata.withNamespace(namespace) +
|
|
|
|
secret.withType('kubernetes.io/tls') +
|
|
|
|
secret.withData(
|
|
|
|
{
|
2020-03-02 20:46:38 +01:00
|
|
|
'tls.crt': std.base64(crt),
|
|
|
|
'tls.key': std.base64(key),
|
2020-03-18 22:01:01 +01:00
|
|
|
}
|
|
|
|
)
|
2020-03-02 20:46:38 +01:00
|
|
|
),
|
|
|
|
|
2019-10-09 22:11:17 +02:00
|
|
|
// Creates new basic deployments
|
|
|
|
newDeployment(name, namespace, image, cmd, port):: (
|
|
|
|
local deployment = k.apps.v1.deployment;
|
|
|
|
local container = k.apps.v1.deployment.mixin.spec.template.spec.containersType;
|
|
|
|
local containerPort = container.portsType;
|
|
|
|
|
|
|
|
local con =
|
|
|
|
container.new(name, image)
|
|
|
|
+ (if cmd != null then container.withCommand(cmd) else {})
|
2019-10-11 22:15:14 +02:00
|
|
|
+ container.withPorts(containerPort.newNamed(port, name));
|
2019-10-09 22:11:17 +02:00
|
|
|
|
|
|
|
local c = [con];
|
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
local d = deployment.new(name, 1, c, { app: name })
|
|
|
|
+ deployment.mixin.metadata.withNamespace(namespace)
|
|
|
|
+ deployment.mixin.metadata.withLabels({ app: name })
|
|
|
|
+ deployment.mixin.spec.selector.withMatchLabels({ app: name })
|
|
|
|
+ deployment.mixin.spec.strategy.withType('RollingUpdate')
|
|
|
|
+ deployment.mixin.spec.template.spec.withRestartPolicy('Always');
|
2019-10-09 22:11:17 +02:00
|
|
|
d
|
|
|
|
),
|
|
|
|
|
|
|
|
newService(name, namespace, port):: (
|
|
|
|
local service = k.core.v1.service;
|
|
|
|
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
|
|
|
local p = servicePort.newNamed(name, port, port);
|
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
local s = service.new(name, { app: name }, p)
|
|
|
|
+ service.mixin.metadata.withNamespace(namespace)
|
|
|
|
+ service.mixin.metadata.withLabels({ app: name });
|
2019-10-09 22:11:17 +02:00
|
|
|
s
|
|
|
|
),
|
|
|
|
|
2019-09-27 00:02:33 +02:00
|
|
|
// Creates http ServiceMonitor objects
|
2021-10-08 20:46:39 +02:00
|
|
|
newServiceMonitor(name, namespace, matchLabel, matchNamespace, portName, portScheme, path='metrics', interval='30s', timeout='30s'):: (
|
2019-09-27 00:02:33 +02:00
|
|
|
{
|
2020-03-18 22:01:01 +01:00
|
|
|
apiVersion: 'monitoring.coreos.com/v1',
|
|
|
|
kind: 'ServiceMonitor',
|
|
|
|
metadata: {
|
|
|
|
name: name,
|
|
|
|
namespace: namespace,
|
|
|
|
labels: {
|
|
|
|
app: name,
|
2019-09-27 00:02:33 +02:00
|
|
|
},
|
2020-03-18 22:01:01 +01:00
|
|
|
},
|
|
|
|
spec: {
|
|
|
|
jobLabel: name + '-exporter',
|
|
|
|
selector: {
|
|
|
|
matchLabels: matchLabel,
|
|
|
|
},
|
|
|
|
endpoints: [
|
|
|
|
{
|
|
|
|
port: portName,
|
|
|
|
scheme: portScheme,
|
2021-10-08 20:46:39 +02:00
|
|
|
interval: interval,
|
|
|
|
scrapeTimeout: timeout,
|
2020-05-26 00:14:28 +02:00
|
|
|
relabelings: [
|
|
|
|
{
|
|
|
|
action: 'replace',
|
|
|
|
regex: '(.*)',
|
|
|
|
replacement: '$1',
|
|
|
|
sourceLabels: ['__meta_kubernetes_pod_node_name'],
|
|
|
|
targetLabel: 'instance',
|
|
|
|
},
|
|
|
|
],
|
2019-09-27 00:02:33 +02:00
|
|
|
},
|
2020-03-18 22:01:01 +01:00
|
|
|
],
|
|
|
|
namespaceSelector: {
|
|
|
|
matchNames: [matchNamespace],
|
2019-09-27 00:02:33 +02:00
|
|
|
},
|
2020-03-18 22:01:01 +01:00
|
|
|
},
|
2019-09-27 00:02:33 +02:00
|
|
|
}
|
|
|
|
),
|
|
|
|
|
|
|
|
// Creates https ServiceMonitor objects
|
|
|
|
newServiceMonitorHTTPS(name, namespace, matchLabel, matchNamespace, portName, portScheme, token):: (
|
|
|
|
local s = $.newServiceMonitor(name, namespace, matchLabel, matchNamespace, portName, portScheme);
|
|
|
|
// Replace endpoint with https and token
|
|
|
|
local t = {
|
|
|
|
spec: {
|
|
|
|
endpoints: [{
|
2020-03-18 22:01:01 +01:00
|
|
|
port: portName,
|
|
|
|
scheme: portScheme,
|
|
|
|
interval: '30s',
|
|
|
|
bearerTokenFile: token,
|
|
|
|
tlsConfig: {
|
|
|
|
insecureSkipVerify: true,
|
|
|
|
},
|
2020-05-26 00:14:28 +02:00
|
|
|
relabelings: [
|
|
|
|
{
|
|
|
|
action: 'replace',
|
|
|
|
regex: '(.*)',
|
|
|
|
replacement: '$1',
|
|
|
|
sourceLabels: ['__meta_kubernetes_pod_node_name'],
|
|
|
|
targetLabel: 'instance',
|
|
|
|
},
|
|
|
|
],
|
2020-03-18 22:01:01 +01:00
|
|
|
}],
|
|
|
|
},
|
2019-09-27 00:02:33 +02:00
|
|
|
};
|
2019-10-09 16:26:42 +02:00
|
|
|
std.mergePatch(s, t)
|
2019-09-27 00:02:33 +02:00
|
|
|
),
|
2019-10-11 22:15:14 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
// Adds arguments to a container in a deployment
|
|
|
|
// args is an array of arguments in the format
|
|
|
|
// ["arg1","arg2",]
|
|
|
|
addArguments(deployment, container, args):: (
|
|
|
|
{ spec+: {
|
|
|
|
template+: {
|
|
|
|
spec+: {
|
|
|
|
containers:
|
|
|
|
std.map(
|
|
|
|
function(c)
|
|
|
|
if c.name == container then
|
|
|
|
c { args+: args }
|
|
|
|
else c,
|
|
|
|
super.containers
|
|
|
|
),
|
2019-10-11 22:15:14 +02:00
|
|
|
},
|
2020-03-18 22:01:01 +01:00
|
|
|
},
|
|
|
|
} }
|
|
|
|
),
|
2019-10-11 22:15:14 +02:00
|
|
|
|
2020-03-18 22:01:01 +01:00
|
|
|
// Adds environment variables to a container in a deployment
|
|
|
|
// envs is an array of environment variables in the format
|
|
|
|
// [{name: 'VARNAME', value: 'var_value'},{...},]
|
|
|
|
addEnviromnentVars(deployment, container, envs):: (
|
|
|
|
{ spec+: {
|
|
|
|
template+: {
|
|
|
|
spec+: {
|
|
|
|
containers:
|
|
|
|
std.map(
|
|
|
|
function(c)
|
|
|
|
if c.name == container then
|
|
|
|
c { env+: envs }
|
|
|
|
else c,
|
|
|
|
super.containers
|
|
|
|
),
|
2019-10-11 22:15:14 +02:00
|
|
|
},
|
2020-03-18 22:01:01 +01:00
|
|
|
},
|
|
|
|
} }
|
|
|
|
),
|
2020-03-01 18:14:06 +01:00
|
|
|
}
|