Skip to content

Commit 91fbaad

Browse files
ArthurSensroboquat
authored andcommitted
werft: Replace terraform with gcloud nodejs lib
Signed-off-by: ArthurSens <[email protected]>
1 parent 21263bd commit 91fbaad

File tree

7 files changed

+1124
-941
lines changed

7 files changed

+1124
-941
lines changed

.werft/dns/main.tf

Lines changed: 0 additions & 56 deletions
This file was deleted.

.werft/dns/variables.tf

Lines changed: 0 additions & 28 deletions
This file was deleted.

.werft/dns/versions.tf

Lines changed: 0 additions & 18 deletions
This file was deleted.

.werft/jobs/build/deploy-to-preview-environment.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { JobConfig } from "./job-config";
1212
import * as VM from '../../vm/vm'
1313
import { Analytics, Installer } from "./installer/installer";
1414
import { previewNameFromBranchName } from "../../util/preview";
15+
import { createDNSRecord } from "../../util/gcloud";
1516

1617
// used by both deploys (helm and Installer)
1718
const PROXY_SECRET_NAME = "proxy-config-certificates";
@@ -639,14 +640,15 @@ interface DeploymentConfig {
639640
}
640641

641642
async function addDNSRecord(werft: Werft, namespace: string, domain: string, isLoadbalancer: boolean, kubeconfigPath: string) {
643+
const coreDevIngressIP = getCoreDevIngressIP()
642644
let wsProxyLBIP = null
643645
if (isLoadbalancer === true) {
644646
werft.log(installerSlices.DNS_ADD_RECORD, "Getting ws-proxy loadbalancer IP");
645647
for (let i = 0; i < 60; i++) {
646648
try {
647649
let lb = exec(`kubectl --kubeconfig ${kubeconfigPath} -n ${namespace} get service ws-proxy -o=jsonpath='{.status.loadBalancer.ingress[0].ip}'`, { silent: true })
648650
if (lb.length > 4) {
649-
wsProxyLBIP = lb
651+
wsProxyLBIP = lb.toString()
650652
break
651653
}
652654
await sleep(1000)
@@ -659,22 +661,14 @@ async function addDNSRecord(werft: Werft, namespace: string, domain: string, isL
659661
}
660662
werft.log(installerSlices.DNS_ADD_RECORD, "Get ws-proxy loadbalancer IP: " + wsProxyLBIP);
661663
} else {
662-
wsProxyLBIP = getCoreDevIngressIP()
664+
wsProxyLBIP = coreDevIngressIP
663665
}
664666

665-
var cmd = `set -x \
666-
&& cd /workspace/.werft/dns \
667-
&& rm -rf .terraform* \
668-
&& export GOOGLE_APPLICATION_CREDENTIALS="${GCLOUD_SERVICE_ACCOUNT_PATH}" \
669-
&& terraform init -backend-config='prefix=${namespace}' -migrate-state -upgrade \
670-
&& terraform apply -auto-approve \
671-
-var 'dns_zone_domain=gitpod-dev.com' \
672-
-var 'domain=${domain}' \
673-
-var 'ingress_ip=${getCoreDevIngressIP()}' \
674-
-var 'ws_proxy_ip=${wsProxyLBIP}'`;
675-
676-
werft.log(installerSlices.DNS_ADD_RECORD, "Terraform command for create dns record: " + cmd)
677-
exec(cmd, { ...metaEnv(), slice: installerSlices.DNS_ADD_RECORD });
667+
await Promise.all([
668+
createDNSRecord(domain, 'gitpod-dev-com', coreDevIngressIP, installerSlices.DNS_ADD_RECORD),
669+
createDNSRecord(`*.${domain}`, 'gitpod-dev-com', coreDevIngressIP, installerSlices.DNS_ADD_RECORD),
670+
createDNSRecord(`*.ws-dev.${domain}`, 'gitpod-dev-com', wsProxyLBIP, installerSlices.DNS_ADD_RECORD),
671+
])
678672
werft.done(installerSlices.DNS_ADD_RECORD);
679673
}
680674

.werft/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"run": "npx ts-node build.ts"
88
},
99
"dependencies": {
10+
"@google-cloud/dns": "^2.2.4",
1011
"@grpc/grpc-js": "^1.4.1",
1112
"@opentelemetry/api": "^1.0.3",
1213
"@opentelemetry/auto-instrumentations-node": "^0.26.0",
@@ -21,7 +22,7 @@
2122
"@types/node": "^16.11.0",
2223
"@types/semver": "7.3.5",
2324
"@types/shelljs": "^0.8.8",
24-
"typescript": "~4.4.2",
25-
"tslib": "^2.3.0"
25+
"tslib": "^2.3.0",
26+
"typescript": "~4.4.2"
2627
}
2728
}

.werft/util/gcloud.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { exec } from './shell';
22
import { sleep } from './util';
33
import { getGlobalWerftInstance } from './werft';
4+
import { DNS, Record, Zone } from '@google-cloud/dns';
5+
import { GCLOUD_SERVICE_ACCOUNT_PATH } from '../jobs/build/const';
46

57
export async function deleteExternalIp(phase: string, name: string, region = "europe-west1") {
68
const werft = getGlobalWerftInstance()
@@ -33,3 +35,54 @@ export async function deleteExternalIp(phase: string, name: string, region = "eu
3335
function getExternalIp(name: string, region = "europe-west1") {
3436
return exec(`gcloud compute addresses describe ${name} --region ${region}| grep 'address:' | cut -c 10-`, { silent: true }).trim();
3537
}
38+
39+
export async function createDNSRecord(domain: string, dnsZone: string, IP: string, slice: string): Promise<void> {
40+
const werft = getGlobalWerftInstance()
41+
42+
const dnsClient = new DNS({ projectId: 'gitpod-dev', keyFilename: GCLOUD_SERVICE_ACCOUNT_PATH })
43+
const zone = dnsClient.zone(dnsZone)
44+
45+
if (!(await matchesExistingRecord(zone, domain, IP))) {
46+
await createOrReplaceRecord(zone, domain, IP, slice)
47+
} else {
48+
werft.log(slice, `DNS Record already exists for domain ${domain}`)
49+
}
50+
}
51+
52+
// matchesExistingRecord will return true only if the existing record matches the same name and IP.
53+
// If IP doesn't match, then the record needs to be replaced in a following step.
54+
async function matchesExistingRecord(zone: Zone, domain: string, IP: string): Promise<boolean> {
55+
const [records] = await zone.getRecords({ name: `${domain}.` })
56+
57+
if (records.length == 0) {
58+
return false
59+
}
60+
61+
let matches = false
62+
records.every(record => {
63+
if (record.metadata.name == `${domain}.` && record.data == IP) {
64+
matches = true
65+
return false // Works as a 'break'
66+
}
67+
return true
68+
})
69+
return matches
70+
}
71+
72+
async function createOrReplaceRecord(zone: Zone, domain: string, IP: string, slice: string): Promise<void> {
73+
const werft = getGlobalWerftInstance()
74+
const record = new Record(zone, 'a', {
75+
name: `${domain}.`,
76+
ttl: 300,
77+
data: IP
78+
})
79+
80+
const [records] = await zone.getRecords({ name: `${domain}.` })
81+
records.forEach(async (record) => {
82+
werft.log(slice, `Deleting old record for ${record.metadata.name} due to IP mismatch.`)
83+
await record.delete()
84+
})
85+
86+
werft.log(slice, `Creating DNS record: ${JSON.stringify(record)}`) // delete before submiting PR
87+
await zone.addRecords(record)
88+
}

0 commit comments

Comments
 (0)