-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
386 lines (311 loc) · 14.4 KB
/
Makefile
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
SHELL := bash# we want bash behaviour in all shell invocations
RED := $(shell tput setaf 1)
GREEN := $(shell tput setaf 2)
YELLOW := $(shell tput setaf 3)
BOLD := $(shell tput bold)
NORMAL := $(shell tput sgr0)
PLATFORM := $(shell uname)
ifneq ($(PLATFORM),Darwin)
$(error $(BOLD)$(RED)Only OS X is currently supported$(NORMAL), please contribute support for your OS)
endif
ifneq (4,$(firstword $(sort $(MAKE_VERSION) 4)))
$(error $(BOLD)$(RED)GNU Make v4 or above is required$(NORMAL), please install with $(BOLD)brew install gmake$(NORMAL) and use $(BOLD)gmake$(NORMAL) instead of make)
endif
BOSH_URL := https://s3.amazonaws.com/bosh-cli-artifacts/bosh-cli-4.0.1-darwin-amd64
### VARS ###
#
# GCP_ACCOUNT :=
# GCP_PROJECT_ID :=
GCP_PROJECT ?= kncf
GCP_REGION ?= europe-west1
GCP_ZONE ?= $(GCP_REGION)-d
K8S_NAME ?= t$(shell date +'%Y%m%d')
K8S_MACHINE_TYPE ?= n1-highcpu-16
K8S_NODES ?= 1
K8S_IMAGE_TYPE ?= UBUNTU
K8S_WAIT_FOR_UPGRADES ?= 300
SCF_RELEASE_VERSION ?= 2.10.1
SCF_RELEASE_URL ?= https://github.com/SUSE/scf/releases/download/$(SCF_RELEASE_VERSION)/scf-opensuse-$(SCF_RELEASE_VERSION).cf1.15.0.0.g647b2273.zip
DNS_ZONE ?= kcf
DNS_ZONE_DESCRIPTION ?= Finger licking good
SCF_DOMAIN ?= $(DNS_ZONE).engineerbetter.com
SCF_ADMIN_PASS ?= admin
UAA_ADMIN_CLIENT_SECRET ?= admin
GIT_SUBMODULES_JOBS ?= 12
FISSILE_STEMCELL ?= splatform/fissile-stemcell-ubuntu:trusty-9.g314b9f4-3.3
DOCKER_ORG ?= engineerbetter
DOCKER := /usr/local/bin/docker
### TARGETS ###
#
#
.DEFAULT_GOAL := help
/usr/local/bin/gcloud:
@brew cask install google-cloud-sdk
gcloud: /usr/local/bin/gcloud
/usr/local/bin/kubectl:
@brew install kubernetes-cli
kubectl: /usr/local/bin/kubectl
/usr/local/bin/helm:
@brew install kubernetes-helm
helm: /usr/local/bin/helm
/usr/local/bin/cf:
@brew install cloudfoundry/tap/cf-cli
cf: /usr/local/bin/cf
$(DOCKER):
@brew install docker
help:
@grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN { FS = "[:#]" } ; { printf "\033[36m%-20s\033[0m %s\n", $$1, $$4 }' | sort
update: gcloud
update: ## Update Google Cloud SDK to latest
@gcloud components update
$(HOME)/.config/gcloud/configurations/config_$(GCP_PROJECT):
@gcloud config configurations create $(GCP_PROJECT) --no-activate
configuration: $(HOME)/.config/gcloud/configurations/config_$(GCP_PROJECT)
zones: gcloud ## Show all zones
@gcloud compute zones list
machines: gcloud ## Show all machine types in the current zone
@gcloud compute machine-types list --filter="zone:($(GCP_ZONE))"
# gcloud compute machine-types describe n1-highmem-4 --zone=europe-west1-d
instances: gcloud ## Show all instances
@gcloud compute instances list
ssh: gcloud ## SSH into an instance
@select INSTANCE in $$(gcloud compute instances list --format="get(name)"); do break; done && \
gcloud compute ssh $$INSTANCE
regions: gcloud ## Show all regions
@gcloud compute regions list
quotas: regions ## Show GCP quotas
config: configuration ## Create gcloud configuration
@gcloud config configurations activate $(GCP_PROJECT) && \
gcloud config set account $$GCP_ACCOUNT && \
gcloud config set project $$GCP_PROJECT_ID && \
gcloud config set compute/region $(GCP_REGION) && \
gcloud config set compute/zone $(GCP_ZONE)
helm_service_account: kubectl helm connect
@(kubectl get serviceaccount helm -n kube-system || kubectl create -f helm-service-account.yml) && \
helm init --service-account helm --wait
k8s:: dns uaa-ip kcf-ip resolve-uaa-kcf ## Set up a new K8S cluster
k8s:: create connect
k8s:: helm_service_account
desc: kubectl connect ## Describe any K8S resource
@kubectl describe $(subst desc,,$(MAKECMDGOALS))
events: kubectl connect ## Show all K8S events
@kubectl get events
ls: gcloud ## Show all K8S clusters
@gcloud container clusters list
cc: gcloud ## Show all available container config options
@gcloud container get-server-config
create: gcloud ## Create a new K8S cluster
@gcloud container clusters describe $(K8S_NAME) >/dev/null || \
(gcloud container clusters create $(K8S_NAME) \
--zone=$(GCP_ZONE) \
--image-type=$(K8S_IMAGE_TYPE) \
--node-locations=$(GCP_ZONE) \
--machine-type=$(K8S_MACHINE_TYPE) \
--num-nodes=$(K8S_NODES) \
--addons=HttpLoadBalancing \
--no-enable-autorepair \
--no-enable-autoupgrade && \
for instance in $$(gcloud compute instances list --filter="metadata.items.key['cluster-name']['value']='$(K8S_NAME)'" --format="get(name)"); \
do \
gcloud compute ssh $$instance -- \
"grep swapaccount=1 /proc/cmdline || (sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT=\"console=ttyS0 net.ifnames=0\"/GRUB_CMDLINE_LINUX_DEFAULT=\"console=ttyS0 net.ifnames=0 swapaccount=1\"/g' /etc/default/grub.d/50-cloudimg-settings.cfg && sudo update-grub && sudo shutdown -r 1)" ;\
done && \
echo -e "\n$(BOLD)$(YELLOW)Giving the cluster $(K8S_WAIT_FOR_UPGRADES)s to perform all upgrades before we continue$(NORMAL)\n" && \
sleep $(K8S_WAIT_FOR_UPGRADES))
contexts: kubectl connect ## Show all contexts
@kubectl config get-contexts
connect: gcloud ## Configure kubectl command line access
@gcloud container clusters get-credentials $(K8S_NAME)
delete: gcloud kubectl ## Delete an existing K8S cluster
@gcloud container clusters delete $(K8S_NAME) ; \
kubectl config unset clusters.gke_$${GCP_PROJECT_ID}_$(GCP_ZONE)_$(K8S_NAME) ; \
kubectl config unset users.gke_$${GCP_PROJECT_ID}_$(GCP_ZONE)_$(K8S_NAME) ; \
kubectl config delete-context gke_$${GCP_PROJECT_ID}_$(GCP_ZONE)_$(K8S_NAME) ; \
kubectl config unset current-context
info: kubectl connect ## Show K8S cluster info
@kubectl cluster-info
nodes: kubectl connect ## Show all K8S nodes
@kubectl get --output=wide nodes
pods: kubectl connect ## Show all K8S pods
@kubectl get --output=wide pods
services: kubectl connect ## Show all K8S services
@kubectl get --output=wide --all-namespaces services
secrets: kubectl connect ## Show all K8S secrets
@kubectl describe --all-namespaces secrets
dashboard: ## Open K8S Dashboard
@open https://console.cloud.google.com/kubernetes/workload
define SCF_CONFIG =
env:
DOMAIN: $(SCF_DOMAIN)
UAA_HOST: uaa.$(SCF_DOMAIN)
UAA_PORT: 2793
EIRINI_KUBE_ENDPOINT: "$(shell kubectl get endpoints kubernetes -o jsonpath={.subsets[0].addresses[0].ip})"
EIRINI_REGISTRY_ADDRESS: "$(shell kubectl get nodes -o jsonpath={.items[*].status.addresses[?\(@.type==\"ExternalIP\"\)].address}):5800"
EIRINI_KUBE_CONFIG: "$(shell kubectl config view --flatten -o json | ruby -ryaml -rjson -e 'puts JSON.generate(YAML.load(ARGF))' | sed 's/\"/\\\"/g')"
services:
UAAloadBalancerIP: $(shell gcloud compute addresses describe $(K8S_NAME)-uaa --region=$(GCP_REGION) --format="get(address)")
KCFloadBalancerIP: $(shell gcloud compute addresses describe $(K8S_NAME)-kcf --region=$(GCP_REGION) --format="get(address)")
loadbalanced: true
kube:
external_ips: [$(shell kubectl get nodes -o jsonpath={.items[*].status.addresses[?\(@.type==\"ExternalIP\"\)].address})]
storage_class:
persistent: "standard"
shared: "shared"
auth: rbac
secrets:
CLUSTER_ADMIN_PASSWORD: $(SCF_ADMIN_PASS)
UAA_ADMIN_CLIENT_SECRET: $(UAA_ADMIN_CLIENT_SECRET)
endef
export SCF_CONFIG
scf-config-values.yml:
@echo "$$SCF_CONFIG" > scf-config-values.yml
.PHONY: scf-config-values.yml
delete-uaa: kubectl helm connect
@kubectl delete namespace uaa && \
helm delete --purge uaa
uaa: scf-config-values.yml k8s helm
@(helm list --deployed | grep uaa) || \
(cd eirini-release/scf && \
echo -e "\n$(BOLD)$(YELLOW)Deploying UAA...$(NORMAL)\n" && \
helm install helm/uaa \
--namespace uaa \
--values ../../scf-config-values.yml \
--name uaa \
--wait)
uaa-ca-cert-secret: kubectl connect
$(eval UAA_CA_CERT_SECRET = $(shell kubectl get pods --namespace uaa -o jsonpath='{.items[*].spec.containers[?(.name=="uaa")].env[?(.name=="INTERNAL_CA_CERT")].valueFrom.secretKeyRef.name}'))
kcf: uaa uaa-ca-cert-secret ## Deploy Cloud Foundry
@(helm list --deployed | grep scf) || \
(cd eirini-release/scf && \
echo -e "\n$(BOLD)$(YELLOW)Deploying CloudFoundry...$(NORMAL)\n" && \
IFS= helm install helm/cf \
--namespace scf \
--values ../../scf-config-values.yml \
--name scf \
--set secrets.UAA_CA_CERT="$$(kubectl get secret $(UAA_CA_CERT_SECRET) --namespace uaa -o jsonpath="{.data['internal-ca-cert']}" | base64 --decode -)" \
--timeout 600 \
--wait)
upgrade-kcf: uaa-ca-cert-secret scf-config-values.yml ## Upgrade Cloud Foundry
@cd eirini-release/scf && \
IFS= helm upgrade scf helm/cf-opensuse \
--namespace scf \
--values ../../scf-config-values.yml \
--set secrets.UAA_CA_CERT="$$(kubectl get secret $(UAA_CA_CERT_SECRET) --namespace uaa -o jsonpath="{.data['internal-ca-cert']}" | base64 --decode -)"
login-kcf: cf ## Login to CF as admin
@cf login -a https://api.$(SCF_DOMAIN) -u admin -p $(SCF_ADMIN_PASS) --skip-ssl-validation
delete-kcf: kubectl helm connect
@kubectl delete namespace scf && \
helm delete --purge scf
upgrade-uaa: scf-config-values.yml ## Upgrade UAA
@cd eirini-release/scf && \
helm upgrade \
--namespace uaa \
--values ../../scf-config-values.yml \
uaa helm/uaa
verify: ## Verify if K8S is ready for SCF
@cd eirini-release/scf && \
./kube-ready-state-check.sh kube
logs: kubectl connect ## Tail pod logs
@select NAMESPACE in $$(kubectl get namespaces -o=name | awk -F/ '{ print $$2 }'); do break; done && \
select POD in $$(kubectl get pods -o=name -n $$NAMESPACE | awk -F/ '{ print $$2 }'); do break; done && \
kubectl logs $$POD -n $$NAMESPACE -f
watch: kubectl connect ## Watch a K8S namespace
@select NAMESPACE in $$(kubectl get namespaces -o=name | awk -F/ '{ print $$2 }'); do break; done && \
watch kubectl get all -n $$NAMESPACE
dns: gcloud ## Setup DNS zone on GCP
@gcloud dns managed-zones describe $(DNS_ZONE) || \
gcloud dns managed-zones create $(DNS_ZONE) --dns-name=$(SCF_DOMAIN). \
--description="$(DNS_ZONE_DESCRIPTION)"
uaa-ip: gcloud ## Create a public IP for UAA
@gcloud compute addresses describe $(K8S_NAME)-uaa --region $(GCP_REGION) || \
gcloud compute addresses create $(K8S_NAME)-uaa --region $(GCP_REGION)
kcf-ip: gcloud ## Create a public IP for KCF
@gcloud compute addresses describe $(K8S_NAME)-kcf --region $(GCP_REGION) || \
gcloud compute addresses create $(K8S_NAME)-kcf --region $(GCP_REGION)
delete-ip: gcloud ## Delete a reserved IP
@gcloud compute addresses list && \
echo -e "\nWhich IP address do you want to delete?" && \
select IP in $$(gcloud compute addresses list --format="get(name)"); do break; done && \
gcloud compute addresses delete $$IP
dns-records: gcloud ## List all DNS records
@gcloud dns record-sets list --zone $(DNS_ZONE)
resolve-uaa-kcf: uaa-ip kcf-ip dns ## Resolve UAA & KCF FQDNs to public LoadBalancers
@rm -f transaction.yaml && \
gcloud dns record-sets transaction start --zone $(DNS_ZONE) && \
export UAA_PREVIOUS_IP=$$(gcloud dns record-sets list --zone kcf --filter="name = uaa.$(SCF_DOMAIN)." --format="get(rrdatas)") && \
(gcloud dns record-sets transaction remove --zone $(DNS_ZONE) --name "uaa.$(SCF_DOMAIN)." --ttl 60 --type A "$$UAA_PREVIOUS_IP" || true) && \
(gcloud dns record-sets transaction remove --zone $(DNS_ZONE) --name "scf.uaa.$(SCF_DOMAIN)." --ttl 60 --type A "$$UAA_PREVIOUS_IP" || true) && \
export UAA_CURRENT_IP=$$(gcloud compute addresses describe $(K8S_NAME)-uaa --region $(GCP_REGION) --format="get(address)") && \
gcloud dns record-sets transaction add --zone $(DNS_ZONE) --name "uaa.$(SCF_DOMAIN)." --ttl 60 --type A "$$UAA_CURRENT_IP" && \
gcloud dns record-sets transaction add --zone $(DNS_ZONE) --name "scf.uaa.$(SCF_DOMAIN)." --ttl 60 --type A "$$UAA_CURRENT_IP" && \
export KCF_PREVIOUS_IP=$$(gcloud dns record-sets list --zone kcf --filter="name = *.$(SCF_DOMAIN)." --format="get(rrdatas)") && \
(gcloud dns record-sets transaction remove --zone $(DNS_ZONE) --name "*.$(SCF_DOMAIN)." --ttl 60 --type A "$$KCF_PREVIOUS_IP" || true) && \
export KCF_CURRENT_IP=$$(gcloud compute addresses describe $(K8S_NAME)-kcf --region $(GCP_REGION) --format="get(address)") && \
gcloud dns record-sets transaction add --zone $(DNS_ZONE) --name "*.$(SCF_DOMAIN)." --ttl 60 --type A "$$KCF_CURRENT_IP" && \
gcloud dns record-sets transaction execute --zone $(DNS_ZONE)
~/go/src/github.com/SUSE/fissile:
@go get -d github.com/SUSE/fissile && \
cd ~/go/src/github.com/SUSE/fissile && \
gmake tools && \
gmake docker-deps && \
gmake all
bin/fissile: ~/go/src/github.com/SUSE/fissile
@cp ~/go/src/github.com/SUSE/fissile/build/darwin-amd64/fissile $(CURDIR)/bin/fissile
/usr/local/bin/wget:
@brew install wget
bin/bosh: /usr/local/bin/wget
@cd $(CURDIR)/bin && \
wget --continue --show-progress --output-document=bosh "$(BOSH_URL)" && \
chmod +x bosh && touch bosh
dev-release: bin/bosh
@cd bosh-simple && $(CURDIR)/bin/bosh create-release --force && \
cd ../scf-helper-release && $(CURDIR)/bin/bosh create-release --force
stemcell: $(DOCKER)
@$(DOCKER) pull $(FISSILE_STEMCELL)
define FISSILE_OPTS
--release bosh-simple,scf-helper-release \
--role-manifest bosh-simple/fissile/role-manifest.yml \
--light-opinions bosh-simple/fissile/opinions.yml \
--dark-opinions bosh-simple/fissile/dark-opinions.yml \
--work-dir $(CURDIR)/tmp \
--docker-organization $(DOCKER_ORG)
endef
packages: dev-release bin/fissile stemcell
@$(CURDIR)/bin/fissile build packages $(FISSILE_OPTS) --stemcell "$(FISSILE_STEMCELL)"
clean-images: $(DOCKER)
@rm -fr $(CURDIR)/tmp/{dockerfiles,compilation} && \
$(DOCKER) images | awk '/^$(DOCKER_ORG)\/fissile/ || /^fissile/ { system("$(DOCKER) rmi -f " $$1":"$$2) }'
images: bin/fissile clean-images packages $(DOCKER)
@$(CURDIR)/bin/fissile build images $(FISSILE_OPTS) --stemcell "$(FISSILE_STEMCELL)" && \
for image in $$($(CURDIR)/bin/fissile show image $(FISSILE_OPTS)); \
do \
$(DOCKER) push $$image; \
done
deployment: bin/fissile
@$(CURDIR)/bin/fissile build kube $(FISSILE_OPTS) --output-dir bosh-simple/kube
chart: images deployment
@$(CURDIR)/bin/fissile build helm $(FISSILE_OPTS) --output-dir bosh-simple/helm
define SIMPLE_CONFIG=
env:
DOMAIN: $(SCF_DOMAIN)
kube:
auth: rbac
secrets:
SPACEBEARS_PASSWORD: $(SCF_ADMIN_PASS)
endef
export SIMPLE_CONFIG
simple-config-values.yml:
@echo "$$SIMPLE_CONFIG" > simple-config-values.yml
.PHONY: simple-config-values.yml
simple: helm simple-config-values.yml chart
@(helm list --deployed | grep simple) || \
(cd bosh-simple && \
echo -e "\n$(BOLD)$(YELLOW)Deploying a simple BOSH release...$(NORMAL)\n" && \
helm install ./helm \
--namespace simple \
--values ../simple-config-values.yml \
--name simple \
--wait)
delete-simple: kubectl helm connect
@kubectl delete namespace simple && \
helm delete --purge simple