mirror of
				https://github.com/carlosedp/cluster-monitoring.git
				synced 2025-10-26 10:23:04 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			286 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet';
 | |
| 
 | |
| {
 | |
|   // Generates the manifests for all objects in kp except those starting with "_"
 | |
|   generate(kp):: (
 | |
|     {
 | |
|       [std.asciiLower(module) + '-' + name]: kp[module][name]
 | |
|       for module in std.objectFieldsAll(kp)
 | |
|       if !std.startsWith(module, '_')
 | |
|       for name in std.objectFields(kp[module])
 | |
|     }
 | |
|   ),
 | |
| 
 | |
|   // 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, {}),
 | |
| 
 | |
|   // Creates serviceaccount
 | |
|   newServiceAccount(name, namespace, labels):: (
 | |
|     local serviceAccount = k.core.v1.serviceAccount;
 | |
| 
 | |
|     serviceAccount.new(name)
 | |
|     + (if labels != null then serviceAccount.mixin.metadata.withLabels(labels) else {})
 | |
|     + serviceAccount.mixin.metadata.withNamespace(namespace)
 | |
|   ),
 | |
| 
 | |
|   // Creates ClusterRoles
 | |
|   // roles format example: [{apis: ['authentication.k8s.io'],
 | |
|   //                        res: ['tokenreviews'],
 | |
|   //                        verbs: ['create']
 | |
|   //                       },[{...}]]
 | |
|   newClusterRole(name, roles, labels):: (
 | |
|     local clusterRole = k.rbac.v1.clusterRole;
 | |
|     local policyRule = clusterRole.rulesType;
 | |
| 
 | |
|     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]);
 | |
| 
 | |
|     local r = [p(pol.apis, pol.res, pol.verbs) for pol in roles];
 | |
| 
 | |
|     local rules = r;
 | |
| 
 | |
|     local c = clusterRole.new()
 | |
|               + (if labels != null then clusterRole.mixin.metadata.withLabels(labels) else {})
 | |
|               + clusterRole.mixin.metadata.withName(name)
 | |
|               + clusterRole.withRules(rules);
 | |
|     c
 | |
|   ),
 | |
| 
 | |
|   // Creates a ClusterRoleBinding between a `clusterRole` and a `serviceAccount` on `serviceAccountNamespace`
 | |
|   newClusterRoleBinding(name, serviceAccount, serviceAccountNamespace, clusterRole, labels):: (
 | |
|     local clusterRoleBinding = k.rbac.v1.clusterRoleBinding;
 | |
| 
 | |
|     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 }])
 | |
|   ),
 | |
| 
 | |
|   // Creates endpoint objects
 | |
|   newEndpoint(name, namespace, ips, portName, portNumber):: (
 | |
|     local endpoints = k.core.v1.endpoints;
 | |
|     local endpointSubset = endpoints.subsetsType;
 | |
|     local endpointPort = endpointSubset.portsType;
 | |
|     local Port = endpointPort.new()
 | |
|                  + endpointPort.withName(portName)
 | |
|                  + endpointPort.withPort(portNumber)
 | |
|                  + endpointPort.withProtocol('TCP');
 | |
| 
 | |
|     local subset = endpointSubset.new()
 | |
|                    + endpointSubset.withAddresses([
 | |
|                      { ip: IP }
 | |
|                      for IP in ips
 | |
|                    ])
 | |
|                    + endpointSubset.withPorts(Port);
 | |
|     endpoints.new()
 | |
|     + endpoints.mixin.metadata.withName(name)
 | |
|     + endpoints.mixin.metadata.withNamespace(namespace)
 | |
|     + endpoints.mixin.metadata.withLabels({ 'k8s-app': name })
 | |
|     + endpoints.withSubsets(subset)
 | |
|   ),
 | |
| 
 | |
|   // 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;
 | |
| 
 | |
|     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)
 | |
|       ),
 | |
|     )
 | |
|   ),
 | |
| 
 | |
|   // 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() +
 | |
|       ingressTls.withHosts(host) +
 | |
|       (if S != '' then { secretName: S } else {})
 | |
|     )
 | |
|   ),
 | |
| 
 | |
|   // Creates a new TLS Secred with Certificate and Key
 | |
|   newTLSSecret(name, namespace, crt, key):: (
 | |
|     local secret = k.core.v1.secret;
 | |
| 
 | |
|     secret.new(name) +
 | |
|     secret.mixin.metadata.withNamespace(namespace) +
 | |
|     secret.withType('kubernetes.io/tls') +
 | |
|     secret.withData(
 | |
|       {
 | |
|         'tls.crt': std.base64(crt),
 | |
|         'tls.key': std.base64(key),
 | |
|       }
 | |
|     )
 | |
|   ),
 | |
| 
 | |
|   // 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 {})
 | |
|       + container.withPorts(containerPort.newNamed(port, name));
 | |
| 
 | |
|     local c = [con];
 | |
| 
 | |
|     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');
 | |
|     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);
 | |
| 
 | |
|     local s = service.new(name, { app: name }, p)
 | |
|               + service.mixin.metadata.withNamespace(namespace)
 | |
|               + service.mixin.metadata.withLabels({ app: name });
 | |
|     s
 | |
|   ),
 | |
| 
 | |
|   // Creates http ServiceMonitor objects
 | |
|   newServiceMonitor(name, namespace, matchLabel, matchNamespace, portName, portScheme, path='metrics'):: (
 | |
|     {
 | |
|       apiVersion: 'monitoring.coreos.com/v1',
 | |
|       kind: 'ServiceMonitor',
 | |
|       metadata: {
 | |
|         name: name,
 | |
|         namespace: namespace,
 | |
|         labels: {
 | |
|           app: name,
 | |
|         },
 | |
|       },
 | |
|       spec: {
 | |
|         jobLabel: name + '-exporter',
 | |
|         selector: {
 | |
|           matchLabels: matchLabel,
 | |
|         },
 | |
|         endpoints: [
 | |
|           {
 | |
|             port: portName,
 | |
|             scheme: portScheme,
 | |
|             interval: '30s',
 | |
|             relabelings: [
 | |
|               {
 | |
|                 action: 'replace',
 | |
|                 regex: '(.*)',
 | |
|                 replacement: '$1',
 | |
|                 sourceLabels: ['__meta_kubernetes_pod_node_name'],
 | |
|                 targetLabel: 'instance',
 | |
|               },
 | |
|             ],
 | |
|           },
 | |
|         ],
 | |
|         namespaceSelector: {
 | |
|           matchNames: [matchNamespace],
 | |
|         },
 | |
|       },
 | |
|     }
 | |
|   ),
 | |
| 
 | |
|   // 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: [{
 | |
|           port: portName,
 | |
|           scheme: portScheme,
 | |
|           interval: '30s',
 | |
|           bearerTokenFile: token,
 | |
|           tlsConfig: {
 | |
|             insecureSkipVerify: true,
 | |
|           },
 | |
|           relabelings: [
 | |
|             {
 | |
|               action: 'replace',
 | |
|               regex: '(.*)',
 | |
|               replacement: '$1',
 | |
|               sourceLabels: ['__meta_kubernetes_pod_node_name'],
 | |
|               targetLabel: 'instance',
 | |
|             },
 | |
|           ],
 | |
|         }],
 | |
|       },
 | |
|     };
 | |
|     std.mergePatch(s, t)
 | |
|   ),
 | |
| 
 | |
|   // 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
 | |
|             ),
 | |
|         },
 | |
|       },
 | |
|     } }
 | |
|   ),
 | |
| 
 | |
|   // 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
 | |
|             ),
 | |
|         },
 | |
|       },
 | |
|     } }
 | |
|   ),
 | |
| }
 |