-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathmonitoring-satellite.ts
125 lines (107 loc) · 5.91 KB
/
monitoring-satellite.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { exec } from '../util/shell';
import { getGlobalWerftInstance } from '../util/werft';
import * as shell from 'shelljs';
import * as fs from 'fs';
/**
* Monitoring satellite deployment bits
*/
export class InstallMonitoringSatelliteParams {
kubeconfigPath: string
satelliteNamespace: string
clusterName: string
nodeExporterPort: number
branch: string
previewDomain: string
stackdriverServiceAccount: any
withVM: boolean
}
const sliceName = 'observability';
/**
* installMonitoringSatellite installs monitoring-satellite, while updating its dependencies to the latest commit in the branch it is running.
*/
export async function installMonitoringSatellite(params: InstallMonitoringSatelliteParams) {
const werft = getGlobalWerftInstance()
werft.log(sliceName, `Cloning observability repository - Branch: ${params.branch}`)
exec(`git clone --branch ${params.branch} https://roboquat:$(cat /mnt/secrets/monitoring-satellite-preview-token/token)@github.com/gitpod-io/observability.git`, {silent: true})
let currentCommit = exec(`git rev-parse HEAD`, {silent: true}).stdout.trim()
let pwd = exec(`pwd`, {silent: true}).stdout.trim()
werft.log(sliceName, `Updating Gitpod's mixin in monitoring-satellite's jsonnetfile.json to latest commit SHA: ${currentCommit}`);
let jsonnetFile = JSON.parse(fs.readFileSync(`${pwd}/observability/jsonnetfile.json`, 'utf8'));
jsonnetFile.dependencies.forEach(dep => {
if(dep.name == 'gitpod') {
dep.version = currentCommit
}
});
fs.writeFileSync(`${pwd}/observability/jsonnetfile.json`, JSON.stringify(jsonnetFile));
exec(`cd observability && jb update`, {slice: sliceName})
let jsonnetRenderCmd = `cd observability && jsonnet -c -J vendor -m monitoring-satellite/manifests \
--ext-code config="{
namespace: '${params.satelliteNamespace}',
clusterName: '${params.satelliteNamespace}',
tracing: {
honeycombAPIKey: '${process.env.HONEYCOMB_API_KEY}',
honeycombDataset: 'preview-environments',
},
previewEnvironment: {
domain: '${params.previewDomain}',
nodeExporterPort: ${params.nodeExporterPort},
},
${params.withVM ? '' : "nodeAffinity: { nodeSelector: { 'gitpod.io/workload_services': 'true' }, }," }
stackdriver: {
defaultProject: '${params.stackdriverServiceAccount.project_id}',
clientEmail: '${params.stackdriverServiceAccount.client_email}',
privateKey: '${params.stackdriverServiceAccount.private_key}',
},
prometheus: {
resources: {
requests: { memory: '200Mi', cpu: '50m' },
},
},
kubescape: {},
}" \
monitoring-satellite/manifests/yaml-generator.jsonnet | xargs -I{} sh -c 'cat {} | gojsontoyaml > {}.yaml' -- {} && \
find monitoring-satellite/manifests -type f ! -name '*.yaml' ! -name '*.jsonnet' -delete`
werft.log(sliceName, 'rendering YAML files')
exec(jsonnetRenderCmd, {silent: true})
if(params.withVM) {
postProcessManifests()
}
// The correct kubectl context should already be configured prior to this step
// Only checks node-exporter readiness for harvester
ensureCorrectInstallationOrder(params.kubeconfigPath, params.satelliteNamespace, params.withVM)
}
async function ensureCorrectInstallationOrder(kubeconfig: string, namespace: string, checkNodeExporterStatus: boolean){
const werft = getGlobalWerftInstance()
werft.log(sliceName, 'installing monitoring-satellite')
exec(`cd observability && hack/deploy-satellite.sh --kubeconfig ${kubeconfig}`, {slice: sliceName})
deployGitpodServiceMonitors(kubeconfig)
checkReadiness(kubeconfig, namespace, checkNodeExporterStatus)
}
async function checkReadiness(kubeconfig: string, namespace: string, checkNodeExporterStatus: boolean) {
// For some reason prometheus' statefulset always take quite some time to get created
// Therefore we wait a couple of seconds
exec(`sleep 30 && kubectl --kubeconfig ${kubeconfig} rollout status -n ${namespace} statefulset prometheus-k8s`, {slice: sliceName, async: true})
exec(`kubectl --kubeconfig ${kubeconfig} rollout status -n ${namespace} deployment grafana`, {slice: sliceName, async: true})
exec(`kubectl --kubeconfig ${kubeconfig} rollout status -n ${namespace} deployment kube-state-metrics`, {slice: sliceName, async: true})
exec(`kubectl --kubeconfig ${kubeconfig} rollout status -n ${namespace} deployment otel-collector`, {slice: sliceName, async: true})
// core-dev is just too unstable for node-exporter
// we don't guarantee that it will run at all
if(checkNodeExporterStatus) {
exec(`kubectl --kubeconfig ${kubeconfig} rollout status -n ${namespace} daemonset node-exporter`, {slice: sliceName, async: true})
}
}
async function deployGitpodServiceMonitors(kubeconfig: string) {
const werft = getGlobalWerftInstance()
werft.log(sliceName, 'installing gitpod ServiceMonitor resources')
exec(`kubectl --kubeconfig ${kubeconfig} apply -f observability/monitoring-satellite/manifests/gitpod/`, {silent: true})
}
function postProcessManifests() {
const werft = getGlobalWerftInstance()
// We're hardcoding nodeports, so we can use them in .werft/vm/manifests.ts
// We'll be able to access Prometheus and Grafana's UI by port-forwarding the harvester proxy into the nodePort
werft.log(sliceName, 'Post-processing manifests so it works on Harvester')
exec(`yq w -i observability/monitoring-satellite/manifests/grafana/service.yaml spec.type 'NodePort'`)
exec(`yq w -i observability/monitoring-satellite/manifests/prometheus/service.yaml spec.type 'NodePort'`)
exec(`yq w -i observability/monitoring-satellite/manifests/prometheus/service.yaml spec.ports[0].nodePort 32001`)
exec(`yq w -i observability/monitoring-satellite/manifests/grafana/service.yaml spec.ports[0].nodePort 32000`)
}