diff --git a/Makefile b/Makefile index 1657010..82e6759 100644 --- a/Makefile +++ b/Makefile @@ -1,55 +1,65 @@ -JSONNET_FMT := jsonnet fmt -n 2 --max-blank-lines 2 --string-style s --comment-style s - GOPATH ?= `$(pwd)` JSONNET_BIN := $(GOPATH)/bin/jsonnet JB_BINARY := $(GOPATH)/bin/jb -.PHONY: generate vendor fmt manifests +JSONNET_FMT := $(GOPATH)/bin/jsonnetfmt -n 2 --max-blank-lines 2 --string-style s --comment-style s -all: manifests +.PHONY: generate vendor fmt manifests help -manifests: jsonnet +all: manifests ## Builds the manifests + +help: # Show help + @echo "Makefile targets:" + @echo "" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +manifests: $(JSONNET_BIN) ## Builds the manifests rm -rf manifests ./scripts/build.sh main.jsonnet $(JSONNET_BIN) -update: jsonnet_bundler - jb update +update_libs: $(JB_BINARY) ## Updates vendor libs. Require a regeneration of the manifests + $(JB_BINARY) update -vendor: jsonnet_bundler jsonnetfile.json jsonnetfile.lock.json +vendor: $(JB_BINARY) jsonnetfile.json jsonnetfile.lock.json ## Download vendor libs rm -rf vendor $(JB_BINARY) install -fmt: - find . -name 'vendor' -prune -o -name '*.libsonnet' -o -name '*.jsonnet' -print | xargs -n 1 -- $(JSONNET_FMT) -i +fmt: ## Formats all jsonnet and libsonnet files (except on vendor dir) + @echo "Formatting jsonnet files" + @find . -name 'vendor' -prune -o -name '*.libsonnet' -o -name '*.jsonnet' -print | xargs -n 1 -- $(JSONNET_FMT) -i -deploy: manifests +deploy: manifests ## Rebuilds manifests and deploy to configured cluster kubectl apply -f ./manifests/ echo "Will wait 40 seconds to reapply manifests" sleep 40 kubectl apply -f ./manifests/ -teardown: +teardown: ## Delete all monitoring stack resources from configured cluster kubectl delete -f ./manifests/ -tar: manifests - rm -rf manifests.tar - tar -cf manifests.tar manifests +tar: manifests ## Generates a .tar.gz from manifests dir + rm -rf manifests.tar.gz + tar -cfz manifests.tar.gz manifests -jsonnet_bundler: -ifeq (, $(shell which jb)) +$(JB_BINARY): ## Installs jsonnet-bundler utility @echo "Installing jsonnet-bundler" @go get -u github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb -endif -jsonnet: -ifeq (, $(shell which jsonnet)) +$(JSONNET_BIN): ## Installs jsonnet and jsonnetfmt utility @echo "Installing jsonnet" - @go get github.com/google/go-jsonnet/cmd/jsonnet - @go get github.com/brancz/gojsontoyaml -endif + @go get -u github.com/google/go-jsonnet/cmd/jsonnet + @go get -u github.com/google/go-jsonnet/cmd/jsonnetfmt + @go get -u github.com/brancz/gojsontoyaml -change_suffix: +update_tools: ## Updates jsonnet, jsonnetfmt and jb utilities + @echo "Updating jsonnet" + @go get -u github.com/google/go-jsonnet/cmd/jsonnet + @go get -u github.com/google/go-jsonnet/cmd/jsonnetfmt + @go get -u github.com/brancz/gojsontoyaml + @go get -u github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb + +change_suffix: ## Changes suffix for the ingress @perl -p -i -e 's/^(\s*)\-\ host:.*/\1- host: alertmanager.${IP}.nip.io/g' manifests/ingress-alertmanager.yaml manifests/ingress-prometheus.yaml manifests/ingress-grafana.yaml @echo "Ingress IPs changed to [service].${IP}.nip.io" ${K3S} kubectl apply -f manifests/ingress-alertmanager.yaml diff --git a/arm_exporter.jsonnet b/arm_exporter.jsonnet index f7bfe11..90a4b81 100644 --- a/arm_exporter.jsonnet +++ b/arm_exporter.jsonnet @@ -20,14 +20,16 @@ local utils = import 'utils.libsonnet'; clusterRole: utils.newClusterRole('arm-exporter', [ - {apis: ['authentication.k8s.io'], - res: ['tokenreviews'], - verbs: ['create'] + { + apis: ['authentication.k8s.io'], + res: ['tokenreviews'], + verbs: ['create'], + }, + { + apis: ['authorization.k8s.io'], + res: ['subjectaccessreviews'], + verbs: ['create'], }, - {apis: ['authorization.k8s.io'], - res: ['subjectaccessreviews'], - verbs: ['create'] - } ], null), clusterRoleBinding: @@ -86,9 +88,10 @@ local utils = import 'utils.libsonnet'; service.mixin.spec.withClusterIp('None'), serviceMonitor: - utils.newServiceMonitorHTTPS('arm-exporter', + utils.newServiceMonitorHTTPS( + 'arm-exporter', $._config.namespace, - {'k8s-app': 'arm-exporter'}, + { 'k8s-app': 'arm-exporter' }, $._config.namespace, 'https', 'https', diff --git a/elasticsearch_exporter.jsonnet b/elasticsearch_exporter.jsonnet index b29f21a..595dab6 100644 --- a/elasticsearch_exporter.jsonnet +++ b/elasticsearch_exporter.jsonnet @@ -82,19 +82,21 @@ local utils = import 'utils.libsonnet'; utils.newServiceMonitor( 'elasticsearch', $._config.namespace, - {'k8s-app': 'elasticsearch-exporter'}, + { 'k8s-app': 'elasticsearch-exporter' }, 'monitoring', 'es-metrics', - 'http'), + 'http' + ), serviceMonitorFluentd: utils.newServiceMonitor( 'fluentd-es', $._config.namespace, - {'k8s-app': 'fluentd-es'}, + { 'k8s-app': 'fluentd-es' }, 'logging', 'metrics', - 'http'), + 'http' + ), }, // Add Prometheus monitoring rules for ElasticSearch prometheusRules+:: { diff --git a/metallb.jsonnet b/metallb.jsonnet index 8aa7c4f..4050653 100644 --- a/metallb.jsonnet +++ b/metallb.jsonnet @@ -13,7 +13,7 @@ local utils = import 'utils.libsonnet'; metallbExporter+:: { serviceMonitor: - utils.newServiceMonitor('metallb', $._config.namespace, {'k8s-app': 'metallb-controller'}, 'metallb-system', 'http', 'http'), + utils.newServiceMonitor('metallb', $._config.namespace, { 'k8s-app': 'metallb-controller' }, 'metallb-system', 'http', 'http'), service: local service = k.core.v1.service; diff --git a/traefik.jsonnet b/traefik.jsonnet index afbc444..7acd3d5 100644 --- a/traefik.jsonnet +++ b/traefik.jsonnet @@ -12,6 +12,6 @@ local utils = import 'utils.libsonnet'; traefikExporter+:: { serviceMonitor: - utils.newServiceMonitor('traefik', $._config.namespace, {'app': 'traefik'}, 'kube-system', 'metrics', 'http'), + utils.newServiceMonitor('traefik', $._config.namespace, { app: 'traefik' }, 'kube-system', 'metrics', 'http'), }, } diff --git a/ups_exporter.jsonnet b/ups_exporter.jsonnet index 3cb261a..5d9560c 100644 --- a/ups_exporter.jsonnet +++ b/ups_exporter.jsonnet @@ -17,7 +17,7 @@ local utils = import 'utils.libsonnet'; upsExporter+:: { serviceMonitor: - utils.newServiceMonitor('ups-exporter', $._config.namespace, {'k8s-app': 'ups-exporter'}, $._config.namespace, 'metrics', 'http'), + utils.newServiceMonitor('ups-exporter', $._config.namespace, { 'k8s-app': 'ups-exporter' }, $._config.namespace, 'metrics', 'http'), service: local service = k.core.v1.service; diff --git a/utils.libsonnet b/utils.libsonnet index a3d0a6d..7552647 100644 --- a/utils.libsonnet +++ b/utils.libsonnet @@ -5,7 +5,8 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; generate(kp):: ( { [std.asciiLower(module) + '-' + name]: kp[module][name] - for module in std.objectFieldsAll(kp) if !std.startsWith(module, '_') + for module in std.objectFieldsAll(kp) + if !std.startsWith(module, '_') for name in std.objectFields(kp[module]) } ), @@ -21,11 +22,11 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; // Creates serviceaccount newServiceAccount(name, namespace, labels):: ( - local serviceAccount = k.core.v1.serviceAccount; + local serviceAccount = k.core.v1.serviceAccount; - serviceAccount.new(name) - + (if labels != null then serviceAccount.mixin.metadata.withLabels(labels) else {}) - + serviceAccount.mixin.metadata.withNamespace(namespace) + serviceAccount.new(name) + + (if labels != null then serviceAccount.mixin.metadata.withLabels(labels) else {}) + + serviceAccount.mixin.metadata.withNamespace(namespace) ), // Creates ClusterRoles @@ -33,38 +34,38 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; // res: ['tokenreviews'], // verbs: ['create'] // },[{...}]] - newClusterRole(name, roles, labels):: ( - local clusterRole = k.rbac.v1.clusterRole; - local policyRule = clusterRole.rulesType; + 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 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 r = [p(pol.apis, pol.res, pol.verbs) for pol in roles]; - local rules = r; + 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 - ), + 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; + // 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 }]) - ), + 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):: ( @@ -72,22 +73,22 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; local endpointSubset = endpoints.subsetsType; local endpointPort = endpointSubset.portsType; local Port = endpointPort.new() - + endpointPort.withName(portName) - + endpointPort.withPort(portNumber) - + endpointPort.withProtocol('TCP'); + + endpointPort.withName(portName) + + endpointPort.withPort(portNumber) + + endpointPort.withProtocol('TCP'); local subset = endpointSubset.new() - + endpointSubset.withAddresses([ - { ip: IP } - for IP in ips - ]) - + endpointSubset.withPorts(Port); + + 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) - ), + + 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):: ( @@ -120,8 +121,8 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; I + ingress.mixin.spec.withTls( ingressTls.new() + - ingressTls.withHosts(host) + - (if S != '' then {'secretName': S} else {}) + ingressTls.withHosts(host) + + (if S != '' then { secretName: S } else {}) ) ), @@ -130,13 +131,14 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; local secret = k.core.v1.secret; secret.new('ingress-secret') + - secret.mixin.metadata.withNamespace(namespace) + - secret.withType('kubernetes.io/tls') + - secret.withData( - { + 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 @@ -152,12 +154,12 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; 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'); + 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 ), @@ -166,40 +168,40 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; 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}); + 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, - }, + 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', - }, - ], - namespaceSelector: { - matchNames: [matchNamespace], - }, + }, + spec: { + jobLabel: name + '-exporter', + selector: { + matchLabels: matchLabel, }, + endpoints: [ + { + port: portName, + scheme: portScheme, + interval: '30s', + }, + ], + namespaceSelector: { + matchNames: [matchNamespace], + }, + }, } ), @@ -210,58 +212,58 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; local t = { spec: { endpoints: [{ - port: portName, - scheme: portScheme, - interval: '30s', - bearerTokenFile: token, - tlsConfig: { - insecureSkipVerify: true, - } - }], - } + port: portName, + scheme: portScheme, + interval: '30s', + bearerTokenFile: token, + tlsConfig: { + insecureSkipVerify: true, + }, + }], + }, }; std.mergePatch(s, t) // 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 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 - ), - }, + // 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 + ), }, - }} - ), + }, + } } + ), }