-
Notifications
You must be signed in to change notification settings - Fork 26
/
Makefile
905 lines (767 loc) · 41.7 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
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
.PHONY: help
help:
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-18s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
#
# If you want to see the full commands, run:
# NOISY_BUILD=y make
#
ifeq ($(NOISY_BUILD),)
ECHO_PREFIX=@
CMD_PREFIX=@
PIPE_DEV_NULL=> /dev/null 2> /dev/null
SWAG_ARGS?=--quiet
GOTESTSUM_FMT=standard-quiet
else
ECHO_PREFIX=@\#
CMD_PREFIX=
PIPE_DEV_NULL=
SWAG_ARGS?=
GOTESTSUM_FMT=standard-verbose
endif
# Pinned container image tags. Check for updates periodically.
OPA_IMAGE:=docker.io/openpolicyagent/opa:latest@sha256:62469564756440afc4a9cb87d1875a0b462a12721260404b967a8a06f9410d17
PRETTIER_IMAGE:=tmknom/prettier:3.0.3
MKDOCS_MATERIAL_IMAGE:=squidfunk/mkdocs-material:9.4
NEXODUS_VERSION?=$(shell date +%Y.%m.%d)
NEXODUS_RELEASE?=$(shell git describe --always --abbrev=6 --exclude qa --exclude prod)
NEXODUS_GCFLAGS?=
NEXODUS_KUBE_CONTEXT?=kind-nexodus-dev
NEXODUS_KUBE_NAMESPACE?=nexodus
kubectl:=kubectl --context=$(NEXODUS_KUBE_CONTEXT) --namespace=$(NEXODUS_KUBE_NAMESPACE)
NEXODUS_BUILD_PROFILE?=dev
NEXODUS_LDFLAGS:=$(NEXODUS_LDFLAGS) -X main.Version=$(NEXODUS_VERSION)-$(NEXODUS_RELEASE)
ifeq ($(NEXODUS_BUILD_PROFILE),dev)
NEXODUS_LDFLAGS+=-X main.DefaultServiceURL=https://try.nexodus.127.0.0.1.nip.io
NEXODUS_GCFLAGS+=all=-N -l
else ifeq ($(NEXODUS_BUILD_PROFILE),qa)
NEXODUS_LDFLAGS+=-X main.DefaultServiceURL=https://qa.nexodus.io
else ifeq ($(NEXODUS_BUILD_PROFILE),prod)
NEXODUS_LDFLAGS+=-X main.DefaultServiceURL=https://try.nexodus.io
endif
CGO_ENABLED?=0
ifeq ($(NEXODUS_RACE_DETECTOR),1)
CGO_ENABLED=1
NEXODUS_BUILD_FLAGS+=-race
endif
ifneq ($(NEXODUS_PPROF),)
NEXODUS_BUILD_FLAGS+=-tags pprof
endif
ifneq ($(NEXODUS_BUILD_TAGS),)
NEXODUS_BUILD_FLAGS+=-tags $(NEXODUS_BUILD_TAGS)
endif
ifeq ($(CGO_ENABLED),0)
NEXODUS_LDFLAGS+=-extldflags=-static
endif
SWAGGER_YAML:=internal/docs/swagger.yaml
PRIVATE_SWAGGER_YAML:=internal/docs-private/swagger.yaml
# Crunchy DB operator does not work well on arm64, use an different overlay to work around it.
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_M),arm64)
OVERLAY?=arm64
else
OVERLAY?=dev
endif
##@ All
.PHONY: all
all: gen-openapi-client generate png-lint go-lint yaml-lint md-lint ui-lint opa-lint action-lint apiserver nexd nexctl ## Run linters and build nexd
##@ Binaries
.PHONY: apiserver
apiserver: dist/apiserver dist/apiserver-pprof
.PHONY: nexd
nexd: dist/nexd dist/nexd-pprof dist/nexd-linux-arm dist/nexd-linux-arm64 dist/nexd-linux-amd64 dist/nexd-darwin-amd64 dist/nexd-darwin-arm64 dist/nexd-windows-amd64.exe ## Build the nexd binary for all architectures
.PHONY: nexd-kstore
nexd-kstore: dist/nexd-kstore ## Build the nexd-kstore binary
.PHONY: nexctl
nexctl: dist/nexctl dist/nexctl-linux-arm dist/nexctl-linux-arm64 dist/nexctl-linux-amd64 dist/nexctl-darwin-amd64 dist/nexctl-darwin-arm64 dist/nexctl-windows-amd64.exe ## Build the nexctl binary for all architectures
# Use go list to find all the go files that make up a binary.
NEXD_DEPS:= $(shell go list -deps -f '{{if (and .Module (eq .Module.Path "github.com/nexodus-io/nexodus"))}}{{$$dir := .Dir}}{{range .GoFiles}}{{$$dir}}/{{.}} {{end}}{{end}}' ./cmd/nexd)
NEXD_KSTORE_DEPS:=$(shell go list -deps -f '{{if (and .Module (eq .Module.Path "github.com/nexodus-io/nexodus"))}}{{$$dir := .Dir}}{{range .GoFiles}}{{$$dir}}/{{.}} {{end}}{{end}}' ./cmd/nexd-kstore)
NEXCTL_DEPS:= $(shell go list -deps -f '{{if (and .Module (eq .Module.Path "github.com/nexodus-io/nexodus"))}}{{$$dir := .Dir}}{{range .GoFiles}}{{$$dir}}/{{.}} {{end}}{{end}}' ./cmd/nexctl)
APISERVER_DEPS:= $(shell go list -deps -f '{{if (and .Module (eq .Module.Path "github.com/nexodus-io/nexodus"))}}{{$$dir := .Dir}}{{range .GoFiles}}{{$$dir}}/{{.}} {{end}}{{end}}' ./cmd/apiserver)
NEX_ALL_GO:= $(shell go list -deps -f '{{if (and .Module (eq .Module.Path "github.com/nexodus-io/nexodus"))}}{{$$dir := .Dir}}{{range .GoFiles}}{{$$dir}}/{{.}} {{end}}{{end}}' ./...)
TAG=$(shell git rev-parse HEAD)
dist:
$(CMD_PREFIX) mkdir -p $@
dist/apiserver: $(APISERVER_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s $@\n" "[GO BUILD]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) go build $(NEXODUS_BUILD_FLAGS) \
-gcflags="$(NEXODUS_GCFLAGS)" -ldflags="$(NEXODUS_LDFLAGS)" -o $@ ./cmd/apiserver
dist/apiserver-pprof: $(APISERVER_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s $@\n" "[GO BUILD]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) go build $(NEXODUS_BUILD_FLAGS) -tags pprof \
-gcflags="$(NEXODUS_GCFLAGS)" -ldflags="$(NEXODUS_LDFLAGS)" -o $@ ./cmd/apiserver
dist/nexd: $(NEXD_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s $@\n" "[GO BUILD]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) go build $(NEXODUS_BUILD_FLAGS) \
-gcflags="$(NEXODUS_GCFLAGS)" -ldflags="$(NEXODUS_LDFLAGS)" -o $@ ./cmd/nexd
dist/nexd-pprof: $(NEXD_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s $@\n" "[GO BUILD]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) go build $(NEXODUS_BUILD_FLAGS) -tags pprof \
-gcflags="$(NEXODUS_GCFLAGS)" -ldflags="$(NEXODUS_LDFLAGS)" -o $@ ./cmd/nexd
dist/nexctl: $(NEXCTL_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s $@\n" "[GO BUILD]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) go build $(NEXODUS_BUILD_FLAGS) -gcflags="$(NEXODUS_GCFLAGS)" \
-ldflags="$(NEXODUS_LDFLAGS)" -o $@ ./cmd/nexctl
dist/nexd-%: $(NEXD_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s $@\n" "[GO BUILD]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) GOOS=$(word 2,$(subst -, ,$(basename $@))) GOARCH=$(word 3,$(subst -, ,$(basename $@))) \
go build $(NEXODUS_BUILD_FLAGS) -gcflags="$(NEXODUS_GCFLAGS)" \
-ldflags="$(NEXODUS_LDFLAGS)" -o $@ ./cmd/nexd
dist/nexctl-%: $(NEXCTL_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s $@\n" "[GO BUILD]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) GOOS=$(word 2,$(subst -, ,$(basename $@))) GOARCH=$(word 3,$(subst -, ,$(basename $@))) \
go build $(NEXODUS_BUILD_FLAGS) -gcflags="$(NEXODUS_GCFLAGS)" \
-ldflags="$(NEXODUS_LDFLAGS)" -o $@ ./cmd/nexctl
dist/nexd-kstore: $(NEXD_KSTORE_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s $@\n" "[GO BUILD]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) \
go build -tags kubernetes $(NEXODUS_BUILD_FLAGS) -gcflags="$(NEXODUS_GCFLAGS)" \
-ldflags="$(NEXODUS_LDFLAGS)" -o $@ ./cmd/nexd-kstore
dist/packages: \
dist/packages/nexodus-linux-amd64.tar.gz \
dist/packages/nexodus-linux-amd64.tar.gz \
dist/packages/nexodus-linux-arm.tar.gz \
dist/packages/nexodus-linux-arm64.tar.gz \
dist/packages/nexodus-darwin-amd64.tar.gz \
dist/packages/nexodus-darwin-arm64.tar.gz \
dist/packages/nexodus-windows-amd64.zip
dist/packages/%: nexd nexctl $(shell find docs/user-guide/ -iname '*.md')
$(CMD_PREFIX) mkdir -p $(basename $(basename $@))
$(CMD_PREFIX) cp -r docs/user-guide $(basename $(basename $@))/user-guide
$(CMD_PREFIX) cp LICENSE $(basename $(basename $@))
$(CMD_PREFIX) cp README.md $(basename $(basename $@))
$(CMD_PREFIX) cp contrib/bash_autocomplete $(basename $(basename $@))
$(CMD_PREFIX) cp dist/nexd-$(subst nexodus-,,$(basename $(basename $(@F))))$(if $(findstring windows,$@),.exe) $(basename $(basename $@))/nexd$(if $(findstring windows,$@),.exe)
$(CMD_PREFIX) cp dist/nexctl-$(subst nexodus-,,$(basename $(basename $(@F))))$(if $(findstring windows,$@),.exe) $(basename $(basename $@))/nexctl$(if $(findstring windows,$@),.exe)
$(CMD_PREFIX) if test "$(word 2,$(subst -, ,$(shell basename $@)))" = "windows" ; then \
printf " %-12s dist/packages/$(@F)\n" "[ZIP]" ;\
cd dist/packages && zip -q9r $(@F) $(basename $(basename $(@F))) ;\
else \
printf " %-12s dist/packages/$(@F)\n" "[TAR]" ;\
cd dist/packages && tar -czf $(@F) $(basename $(basename $(@F))) ;\
fi
.PHONY: clean
clean: ## clean built binaries
$(CMD_PREFIX) touch ./cmd/apiserver/main.go # to force apidocs to get rebuilt.
$(CMD_PREFIX) rm -rf dist
##@ Development
.PHONY: go-lint
go-lint: dist/.go-lint-linux dist/.go-lint-darwin dist/.go-lint-windows ## Lint the go code
.PHONY: go-lint-prereqs
go-lint-prereqs:
$(CMD_PREFIX) if ! which golangci-lint >/dev/null 2>&1; then \
echo "Please install golangci-lint." ; \
echo "See: https://golangci-lint.run/usage/install/#local-installation" ; \
exit 1 ; \
fi
dist/.go-lint-%: $(NEX_ALL_GO) | go-lint-prereqs gen-docs dist gen-openapi-client $(wildcard internal/api/public/*.go)
$(ECHO_PREFIX) printf " %-12s GOOS=$(word 3,$(subst -, ,$@))\n" "[GO LINT]"
$(CMD_PREFIX) CGO_ENABLED=$(CGO_ENABLED) GOOS=$(word 3,$(subst -, ,$@)) GOARCH=amd64 \
golangci-lint run --build-tags integration --timeout 5m ./...
$(CMD_PREFIX) touch $@
.PHONY: yaml-lint
yaml-lint: dist/.yaml-lint ## Lint the yaml files
# If gen-docs needs to run, make sure it goes first as it generates internal/docs/swagger.yaml
dist/.yaml-lint: $(wildcard */**/*.yaml) | gen-docs dist
$(CMD_PREFIX) if ! which yamllint >/dev/null 2>&1; then \
echo "Please install yamllint." ; \
echo "See: https://yamllint.readthedocs.io/en/stable/quickstart.html" ; \
exit 1 ; \
fi
$(ECHO_PREFIX) printf " %-12s ./...\n" "[YAML LINT]"
$(CMD_PREFIX) yamllint -c .yamllint.yaml deploy --strict
$(CMD_PREFIX) touch $@
.PHONY: k8s-lint
k8s-lint: dist/.k8s-lint ## Lint the kubernetes deployment files
dist/.k8s-lint: $(shell find deploy -type f ) | dist
$(CMD_PREFIX) if ! which kubeconform >/dev/null 2>&1; then \
echo "Please install kubeconform." ; \
echo "With: go install github.com/yannh/kubeconform/cmd/[email protected]" ; \
exit 1 ; \
fi
$(CMD_PREFIX) mkdir -p ./dist/kubeconfigs
$(CMD_PREFIX) kustomize build ./deploy/nexodus/overlays/dev > ./dist/kubeconfigs/dev.yaml
$(CMD_PREFIX) kustomize build ./deploy/nexodus/overlays/prod > ./dist/kubeconfigs/prod.yaml
$(CMD_PREFIX) kustomize build ./deploy/nexodus/overlays/qa > ./dist/kubeconfigs/qa.yaml
$(CMD_PREFIX) kustomize build ./deploy/nexodus/overlays/playground > ./dist/kubeconfigs/playground.yaml
$(CMD_PREFIX) kubeconform -summary -output json -schema-location default -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' -schema-location 'deploy/.crdSchemas/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' ./dist/kubeconfigs/
$(CMD_PREFIX) touch $@
dist/crd-extractor.zip: dist
$(CMD_PREFIX) if [ ! -f $@ ] ; then \
curl -L -s https://github.com/datreeio/CRDs-catalog/releases/latest/download/crd-extractor.zip --output dist/crd-extractor.zip; \
fi
dist/crd-extractor.sh: dist/crd-extractor.zip
$(CMD_PREFIX) cd dist && unzip -o crd-extractor.zip
$(CMD_PREFIX) chmod a+x dist/crd-extractor.sh
$(CMD_PREFIX) touch $@
.PHONY: k8s-crd-extract
k8s-crd-extract: dist/crd-extractor.sh ## Extract the kubernetes CRDs used iin k8s-lint
$(CMD_PREFIX) rm -rf $(HOME)/.datree/crdSchemas
$(CMD_PREFIX) dist/crd-extractor.sh
$(CMD_PREFIX) cp $(HOME)/.datree/crdSchemas/*/* deploy/.crdSchemas
.PHONY: png-lint
png-lint: dist/.png-lint ## Lint the png files from excalidraw
dist/.png-lint: $(shell find . -iname '*.png') | dist
$(ECHO_PREFIX) printf " %-12s ./...\n" "[PNG LINT]"
$(CMD_PREFIX) for file in $^; do \
if echo "$$file" | grep -q --basic-regexp --file=.excalidraw-ignore; then continue ; fi ; \
if ! grep -q "excalidraw+json" $$file; then \
echo "$$file was not exported from excalidraw with 'Embed Scene' enabled." ; \
echo "If this is not an excalidraw file, add it to .excalidraw-ignore" ; \
exit 1 ; \
fi \
done
$(CMD_PREFIX) touch $@
.PHONY: md-lint
md-lint: dist/.md-lint ## Lint markdown files
dist/.md-lint: $(wildcard */**/*.md) | dist
$(ECHO_PREFIX) printf " %-12s ./...\n" "[MD LINT]"
$(CMD_PREFIX) docker run --rm -v $(CURDIR):/workdir docker.io/davidanson/markdownlint-cli2:v0.6.0 > /dev/null
$(CMD_PREFIX) touch $@
.PHONY: ui-lint
ui-lint: dist/.ui-lint ## Lint the UI source
dist/.ui-lint: $(filter-out $(wildcard ui/node_modules/*),$(wildcard ui/*) $(wildcard ui/**/*)) | dist
$(ECHO_PREFIX) printf " %-12s ./...\n" "[UI LINT]"
$(CMD_PREFIX) docker run --rm -v $(CURDIR):/workdir $(PRETTIER_IMAGE) --check /workdir/ui/src/ >/dev/null
$(CMD_PREFIX) touch $@
policies=$(wildcard internal/routers/*.rego)
.PHONY: opa-lint
opa-lint: dist/.opa-lint ## Lint the OPA policies
dist/.opa-lint: $(policies) | dist
$(ECHO_PREFIX) printf " %-12s ./...\n" "[OPA LINT]"
$(CMD_PREFIX) docker run --platform linux/x86_64 --rm -v $(CURDIR):/workdir -w /workdir $(OPA_IMAGE) fmt --fail $(policies) $(PIPE_DEV_NULL)
$(CMD_PREFIX) docker run --platform linux/x86_64 --rm -v $(CURDIR):/workdir -w /workdir $(OPA_IMAGE) test -v $(policies) $(PIPE_DEV_NULL)
$(CMD_PREFIX) touch $@
.PHONY: action-lint
action-lint: dist/.action-lint ## Lint GitHub Action workflows
dist/.action-lint: $(shell find .github -type f) | dist
$(ECHO_PREFIX) printf " %-12s .github/...\n" "[ACTION LINT]"
$(CMD_PREFIX) if ! which actionlint $(PIPE_DEV_NULL) ; then \
echo "Please install actionlint." ; \
echo "go install github.com/rhysd/actionlint/cmd/actionlint@latest" ; \
exit 1 ; \
fi
$(CMD_PREFIX) if ! which shellcheck $(PIPE_DEV_NULL) ; then \
echo "Please install shellcheck." ; \
echo "https://github.com/koalaman/shellcheck#user-content-installing" ; \
exit 1 ; \
fi
$(CMD_PREFIX) actionlint -color
$(CMD_PREFIX) touch $@
# https://github.com/google/go-licenses
# For license IDs: https://github.com/google/licenseclassifier/blob/main/license_type.go
DISALLOWED_LICENSE_TYPES:=forbidden,restricted,unknown
.PHONY: go-licenses
go-licenses: dist/.go-licenses ## Validate licenses of Go dependencies
dist/.go-licenses: $(NEX_ALL_GO) | dist
$(ECHO_PREFIX) printf " %-12s ./...\n" "[GO LICENSES]"
$(CMD_PREFIX) if ! which go-licenses $(PIPE_DEV_NULL) ; then \
echo "Please install go-licenses." ; \
echo "go install github.com/google/go-licenses@latest" ; \
exit 1 ; \
fi
$(CMD_PREFIX) go-licenses check --include_tests --disallowed_types=$(DISALLOWED_LICENSE_TYPES) ./...
$(CMD_PREFIX) touch $@
.PHONY: gen-docs
gen-docs: $(SWAGGER_YAML) $(PRIVATE_SWAGGER_YAML) ## Generate API docs
.PHONY: openapi-lint
openapi-lint: dist/.openapi-lint ## Lint the OpenAPI document
.PHONY: openapi-lint
dist/.openapi-lint: $(SWAGGER_YAML) $(PRIVATE_SWAGGER_YAML) | dist
$(ECHO_PREFIX) printf " %-12s \n" "[OPENAPI LINT]"
$(CMD_PREFIX) docker run --rm -v $(CURDIR):/src openapitools/openapi-generator-cli:v6.5.0 \
validate -i /src/$(SWAGGER_YAML)
$(CMD_PREFIX) docker run --rm -v $(CURDIR):/src openapitools/openapi-generator-cli:v6.5.0 \
validate -i /src/$(PRIVATE_SWAGGER_YAML)
$(CMD_PREFIX) touch $@
$(SWAGGER_YAML): $(APISERVER_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s ./cmd/apiserver/main.go\n" "[PUBLIC API DOCS]"
$(CMD_PREFIX) docker run \--platform linux/x86_64 --rm \
-v $(CURDIR):/workdir -w /workdir \
ghcr.io/swaggo/swag:v1.16.2 \
/root/swag init $(SWAG_ARGS) --tags "!Private" -g ./cmd/apiserver/main.go -o ./internal/docs
$(PRIVATE_SWAGGER_YAML): $(APISERVER_DEPS) | dist
$(ECHO_PREFIX) printf " %-12s ./cmd/apiserver/main.go\n" "[PRIVATE API DOCS]"
$(CMD_PREFIX) docker run \--platform linux/x86_64 --rm \
-v $(CURDIR):/workdir -w /workdir \
ghcr.io/swaggo/swag:v1.16.2 \
/root/swag init $(SWAG_ARGS) --tags "Private" -g ./cmd/apiserver/main.go -o ./internal/docs-private
.PHONY: gen-openapi-client
gen-openapi-client: internal/api/public/client.go ## Generate the OpenAPI Client
internal/api/public/client.go: $(SWAGGER_YAML) | dist
$(ECHO_PREFIX) printf " %-12s $(SWAGGER_YAML)\n" "[OPENAPI CLIENT GEN]"
$(CMD_PREFIX) rm -f $(shell find internal/client | grep .go | grep -v custom_)
$(CMD_PREFIX) docker run --rm -v $(CURDIR):/src --user $(shell id -u):$(shell id -g) \
openapitools/openapi-generator-cli:v6.5.0 \
generate -i /src/$(SWAGGER_YAML) -g go \
--package-name client \
-o /src/internal/client \
--ignore-file-override /src/.openapi-generator-ignore $(PIPE_DEV_NULL)
$(ECHO_PREFIX) printf " %-12s ./...\n" "[GO FMT]"
$(CMD_PREFIX) [ -z "$$(gofmt -l .)" ] || gofmt -w .
internal/api/public/%.go: internal/api/public/client.go
.PHONY: opa-fmt
opa-fmt: ## Lint the OPA policies
$(ECHO_PREFIX) printf " %-12s \n" "[OPA FMT]"
$(CMD_PREFIX) docker run --platform linux/x86_64 --rm -v $(CURDIR):/workdir -w /workdir $(OPA_IMAGE) fmt --write $(policies)
.PHONY: ui-fmt
ui-fmt: dist/.ui-fmt ## Format the UI sources
dist/.ui-fmt: $(wildcard ui/*) $(wildcard ui/src/**) | dist
$(ECHO_PREFIX) printf " %-12s \n" "[UI FMT]"
$(CMD_PREFIX) docker run --rm -v $(CURDIR):/workdir --user $(shell id -u):$(shell id -g) \
$(PRETTIER_IMAGE) --write /workdir/ui/src/ $(PIPE_DEV_NULL)
$(CMD_PREFIX) touch $@
.PHONY: generate
generate: dist/.generate ## Run all code generators and formatters
docs/user-guide/nexd.md: dist/nexd hack/nexd-docs.sh
$(ECHO_PREFIX) printf " %-12s nexd\n" "[DOCS]"
$(CMD_PREFIX) hack/nexd-docs.sh
docs/user-guide/nexctl.md: dist/nexctl hack/nexctl-docs.sh
$(ECHO_PREFIX) printf " %-12s nexctl\n" "[DOCS]"
$(CMD_PREFIX) hack/nexctl-docs.sh
dist/.generate: $(SWAGGER_YAML) $(PRIVATE_SWAGGER_YAML) dist/.ui-fmt docs/user-guide/nexd.md docs/user-guide/nexctl.md | dist
$(ECHO_PREFIX) printf " %-12s \n" "[MOD TIDY]"
$(CMD_PREFIX) go mod tidy
$(ECHO_PREFIX) printf " %-12s ./...\n" "[GO FMT]"
$(CMD_PREFIX) [ -z "$(shell gofmt -l .)" ] || gofmt -w .
$(CMD_PREFIX) touch $@
.PHONEY:e2e-setup
e2e-setup: e2eprereqs dist/nexd dist/nexctl image-nexd image-playwright derpcerts
.PHONY: e2e
e2e: e2e-setup ## Run e2e verbose tests
CGO_ENABLED=1 gotestsum --format $(GOTESTSUM_FMT) -- \
-race --tags=integration ./integration-tests/... $(shell [ -z "$$NEX_TEST" ] || echo "-run $$NEX_TEST" )
.PHONY: e2e-podman
e2e-podman: ## Run e2e tests on podman
go test -c -v --tags=integration ./integration-tests/...
sudo NEXODUS_TEST_PODMAN=1 TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED=true ./integration-tests.test -test.v
.PHONY: test
test: gotestsum-prereqs ## Run unit tests
gotestsum --format $(GOTESTSUM_FMT) -- \
./...
.PHONY: telepresence-connect-f
telepresence-connect-f: telepresence-prereqs
telepresence helm install 2> /dev/null || true ;\
telepresence quit -s || true ;\
telepresence connect --context=$(NEXODUS_KUBE_CONTEXT) --namespace=$(NEXODUS_KUBE_NAMESPACE);\
.PHONY: telepresence-connect
telepresence-connect: telepresence-prereqs
$(CMD_PREFIX) if [ "$(shell telepresence status --output json | jq .user_daemon.status -r)" != "Connected" ]; then \
make telepresence-connect-f ;\
fi
telepresence_%: telepresence-connect
$(CMD_PREFIX) if [ -z "$(shell telepresence status --output json | jq '.user_daemon.intercepts[]|select(.name == "$(word 2,$(subst _, ,$(basename $@)))-nexodus")' 2> /dev/null)" ]; then \
telepresence intercept $(word 2,$(subst _, ,$(basename $@))) --port $(word 3,$(subst _, ,$(basename $@))) --env-json=$(word 2,$(subst _, ,$(basename $@)))-envs.json ;\
echo "=======================================================================================" ;\
echo ;\
echo " Start the $(word 2,$(subst _, ,$(basename $@))) locally with a debugger with the env variables" ;\
echo " with the values found in: $(word 2,$(subst _, ,$(basename $@)))-envs.json" ;\
echo ;\
echo " Hint: use the IDEA EnvFile plugin https://plugins.jetbrains.com/plugin/7861-envfile" ;\
echo ;\
fi
.PHONY: debug-apiserver
debug-apiserver: telepresence-connect ## Use telepresence to debug the apiserver deployment
$(CMD_PREFIX) if [ -z "$(shell telepresence status --output json | jq '.user_daemon.intercepts[]|select(.name == "$(word 2,$(subst _, ,$(basename $@)))-nexodus")' 2> /dev/null)" ]; then \
telepresence intercept apiserver --workload apiserver --service apiserver --port 8080:8080 --env-json=apiserver-envs.json ;\
telepresence intercept apiserver-grpc --workload apiserver --service apiserver --port 5080:5080 ;\
echo "=======================================================================================" ;\
echo ;\
echo " Start the apiserver locally with a debugger with the env variables" ;\
echo " with the values found in: apiserver-envs.json" ;\
echo ;\
echo " Hint: use the IDEA EnvFile plugin https://plugins.jetbrains.com/plugin/7861-envfile" ;\
echo ;\
fi
.PHONY: debug-apiserver-stop
debug-apiserver-stop: telepresence-prereqs ## Stop using telepresence to debug the apiserver deployment
$(CMD_PREFIX) telepresence leave apiserver
$(CMD_PREFIX) telepresence leave apiserver-grpc
dist/.npm-install:
$(CMD_PREFIX) cd ui; npm install
$(CMD_PREFIX) touch $@
.PHONY: debug-frontend
debug-frontend: telepresence_frontend_3000 dist/.npm-install ## Use telepresence to debug the frontend deployment
$(CMD_PREFIX) cd ui; npm start
.PHONY: debug-frontend-stop
debug-frontend-stop: telepresence-prereqs ## Stop using telepresence to debug the frontend deployment
$(CMD_PREFIX) telepresence leave frontend
NEXODUS_LOCAL_IP:=`go run ./hack/localip`
.PHONY: run-nexd-container
run-nexd-container: image-nexd ## Run a container that you can run nexodus in
$(CMD_PREFIX) mkdir -p .certs
$(CMD_PREFIX) docker run --rm -it --network bridge \
--cap-add SYS_MODULE \
--cap-add NET_ADMIN \
--cap-add NET_RAW \
--sysctl net.ipv4.ip_forward=1 \
--sysctl net.ipv6.conf.all.disable_ipv6=0 \
--sysctl net.ipv6.conf.all.forwarding=1 \
--add-host try.nexodus.127.0.0.1.nip.io:$(NEXODUS_LOCAL_IP) \
--add-host api.try.nexodus.127.0.0.1.nip.io:$(NEXODUS_LOCAL_IP) \
--add-host auth.try.nexodus.127.0.0.1.nip.io:$(NEXODUS_LOCAL_IP) \
--mount type=bind,source=$(shell pwd)/.certs,target=/.certs,readonly \
quay.io/nexodus/nexd:latest /update-ca.sh
.PHONY: run-sql-apiserver
run-sql-apiserver: ## runs a command line SQL client to interact with the apiserver database
ifeq ($(OVERLAY),dev)
$(CMD_PREFIX) $(kubectl) exec -it \
$(shell $(kubectl) get pods -l postgres-operator.crunchydata.com/role=master -o name) \
-c database -- psql apiserver
else ifeq ($(OVERLAY),arm64)
$(CMD_PREFIX) $(kubectl) exec -it svc/postgres -c postgres -- psql -U apiserver apiserver
else ifeq ($(OVERLAY),cockroach)
$(CMD_PREFIX) $(kubectl) exec -it svc/cockroachdb -- cockroach sql --insecure --user apiserver --database apiserver
endif
.PHONY: run-sql-ipam
run-sql-ipam: ## runs a command line SQL client to interact with the ipam database
ifeq ($(OVERLAY),dev)
$(CMD_PREFIX) $(kubectl) exec -it \
$(shell $(kubectl) get pods -l postgres-operator.crunchydata.com/role=master -o name) \
-c database -- psql ipam
else ifeq ($(OVERLAY),arm64)
$(CMD_PREFIX) $(kubectl) exec -it svc/postgres -c postgres -- psql -U ipam ipam
else ifeq ($(OVERLAY),cockroach)
$(CMD_PREFIX) $(kubectl) exec -it svc/cockroachdb -- cockroach sql --insecure --user ipam --database ipam
endif
.PHONY: run-sql-keycloak
run-sql-keycloak: ## runs a command line SQL client to interact with the keycloak database
ifeq ($(OVERLAY),dev)
$(CMD_PREFIX) $(kubectl) exec -it \
$(shell $(kubectl) get pods -l postgres-operator.crunchydata.com/role=master -o name) \
-c database -- psql keycloak
else ifeq ($(OVERLAY),arm64)
$(CMD_PREFIX) $(kubectl) exec -it svc/postgres -c postgres -- psql -U keycloak keycloak
else ifeq ($(OVERLAY),cockroach)
$(CMD_PREFIX) $(kubectl) exec -it svc/cockroachdb -- cockroach sql --insecure --user keycloak --database keycloak
endif
.PHONY: clear-db
clear-db:
$(CMD_PREFIX) $(kubectl) scale deployment apiserver --replicas=0 $(PIPE_DEV_NULL)
$(CMD_PREFIX) $(kubectl) rollout status deploy/apiserver --timeout=5m $(PIPE_DEV_NULL)
$(ECHO_PREFIX) printf " %-12s \n" "[DROP TABLES] ..."
$(CMD_PREFIX) echo "\
DROP TABLE IF EXISTS user_identities;\
DROP TABLE IF EXISTS reg_keys;\
DROP TABLE IF EXISTS registration_tokens;\
DROP TABLE IF EXISTS invitations;\
DROP TABLE IF EXISTS security_groups;\
DROP TABLE IF EXISTS device_metadata;\
DROP TABLE IF EXISTS devices;\
DROP TABLE IF EXISTS sites;\
DROP TABLE IF EXISTS service_networks;\
DROP TABLE IF EXISTS user_organizations;\
DROP TABLE IF EXISTS vpcs;\
DROP TABLE IF EXISTS organizations;\
DROP TABLE IF EXISTS users;\
DROP TABLE IF EXISTS apiserver_migrations;\
" | make run-sql-apiserver $(PIPE_DEV_NULL)
$(CMD_PREFIX) $(kubectl) scale deployment apiserver --replicas=1 $(PIPE_DEV_NULL)
$(CMD_PREFIX) $(kubectl) rollout status deploy/apiserver --timeout=5m
$(CMD_PREFIX) $(kubectl) rollout restart statefulset redis $(PIPE_DEV_NULL)
$(CMD_PREFIX) $(kubectl) rollout status statefulset redis --timeout=5m
##@ Container Images
.PHONY: e2eprereqs
e2eprereqs: gotestsum-prereqs
$(CMD_PREFIX) if [ -z "$(shell which kind)" ]; then \
echo "Please install kind and then start the kind dev environment." ; \
echo "https://kind.sigs.k8s.io/" ; \
echo " $$ make run-on-kind" ; \
exit 1 ; \
fi
$(CMD_PREFIX) if [ -z "$(findstring nexodus-dev,$(shell kind get clusters))" ]; then \
echo "Please start the kind dev environment." ; \
echo " $$ make run-on-kind" ; \
exit 1 ; \
fi
.PHONY: gotestsum-prereqs
gotestsum-prereqs:
$(CMD_PREFIX) if [ -z "$(shell which gotestsum)" ]; then \
echo "Please install gotestsum." ; \
echo " $$ ./hack/install-tools.sh" ; \
exit 1 ; \
fi
.PHONY: telepresence-prereqs
telepresence-prereqs: e2eprereqs
@if [ -z "$(shell which telepresence)" ]; then \
echo "Please install telepresence first" ; \
echo "https://www.telepresence.io/docs/latest/quick-start/" ; \
exit 1 ; \
fi
.PHONY: image-frontend
image-frontend:
docker build -f Containerfile.frontend -t quay.io/nexodus/frontend:$(TAG) .
docker tag quay.io/nexodus/frontend:$(TAG) quay.io/nexodus/frontend:latest
.PHONY: image-apiserver
image-apiserver:
docker build -f Containerfile.apiserver \
--build-arg NEXODUS_PPROF="$(NEXODUS_PPROF)" \
--build-arg NEXODUS_RACE_DETECTOR="$(NEXODUS_RACE_DETECTOR)" \
-t quay.io/nexodus/apiserver:$(TAG) .
docker tag quay.io/nexodus/apiserver:$(TAG) quay.io/nexodus/apiserver:latest
.PHONY: image-nexd ## Build the nexodus agent image
image-nexd: dist/.image-nexd
dist/.image-nexd: $(NEXD_DEPS) $(NEXCTL_DEPS) Containerfile.nexd hack/update-ca.sh | dist
$(CMD_PREFIX) docker build -f Containerfile.nexd \
--build-arg NEXODUS_PPROF="$(NEXODUS_PPROF)" \
--build-arg NEXODUS_RACE_DETECTOR="$(NEXODUS_RACE_DETECTOR)" \
-t quay.io/nexodus/nexd:$(TAG) .
$(CMD_PREFIX) docker tag quay.io/nexodus/nexd:$(TAG) quay.io/nexodus/nexd:latest
$(CMD_PREFIX) touch $@
.PHONY: image-ipam ## Build the IPAM image
image-ipam:
docker build -f Containerfile.ipam -t quay.io/nexodus/go-ipam:$(TAG) .
docker tag quay.io/nexodus/go-ipam:$(TAG) quay.io/nexodus/go-ipam:latest
.PHONY: image-envsubst ## Build the IPAM image
image-envsubst:
docker build -f Containerfile.envsubst -t quay.io/nexodus/envsubst:$(TAG) .
docker tag quay.io/nexodus/envsubst:$(TAG) quay.io/nexodus/envsubst:latest
.PHONY: image-playwright ## Build the playwright image
image-playwright: dist/.image-playwright
dist/.image-playwright: Containerfile.playwright hack/update-ca.sh | dist
$(CMD_PREFIX) docker build -f Containerfile.playwright \
-t quay.io/nexodus/playwright:$(TAG) .
$(CMD_PREFIX) docker tag quay.io/nexodus/playwright:$(TAG) quay.io/nexodus/playwright:latest
$(CMD_PREFIX) touch $@
.PHONY: images
images: image-nexd image-frontend image-apiserver image-ipam image-envsubst ## Create container images
##@ Kubernetes - kind dev environment
.PHONY: run-on-kind
run-on-kind: setup-kind install-olm deploy-operators images load-images deploy cacerts ## Setup a kind cluster and deploy nexodus on it
.PHONY: teardown
teardown: ## Teardown the kind cluster
$(CMD_PREFIX) kind delete cluster --name nexodus-dev
.PHONY: setup-kind
setup-kind: teardown ## Create a kind cluster with ingress enabled, but don't install nexodus.
$(CMD_PREFIX) kind create cluster --config ./deploy/kind.yaml
$(CMD_PREFIX) $(kubectl) cluster-info
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) apply -f ./deploy/kind-ingress.yaml
.PHONY: deploy-nexodus-agent ## Deply the nexodus agent in the kind cluster
deploy-nexodus-agent: image-nexd
$(CMD_PREFIX) kind load --name nexodus-dev docker-image quay.io/nexodus/nexd:latest
$(CMD_PREFIX) cp deploy/nexodus-client/overlays/dev/kustomization.yaml.sample deploy/nexodus-client/overlays/dev/kustomization.yaml
$(CMD_PREFIX) sed -i -e "s/<NEXODUS_SERVICE_IP>/$(NEXODUS_LOCAL_IP)/" deploy/nexodus-client/overlays/dev/kustomization.yaml
$(CMD_PREFIX) sed -i -e "s/<NEXODUS_SERVICE_CERT>/$(shell $(kubectl) get secret nexodus-ca-key-pair -o json | jq -r '.data."ca.crt"')/" deploy/nexodus-client/overlays/dev/kustomization.yaml
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) apply -k ./deploy/nexodus-client/overlays/dev
##@ Kubernetes - work with an existing cluster (kind dev env or another one)
.PHONY: install-olm
install-olm: ## Install OLM on the cluster
$(CMD_PREFIX) curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.27.0/install.sh | bash -s v0.27.0
.PHONY: deploy-operators
deploy-operators: ## Deploy all operators and wait for readiness
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) apply -k ./deploy/operators/overlays/$(OVERLAY)
.PHONY: use-cockroach
use-cockroach: ## Recreate the database with a Cockroach based server
$(CMD_PREFIX) OVERLAY=cockroach make recreate-db
.PHONY: use-crunchy
use-crunchy: ## Recreate the database with a Crunchy based postgres server
$(CMD_PREFIX) OVERLAY=dev make recreate-db
.PHONY: use-postgres
use-postgres: ## Recreate the database with a simple Postgres server
$(CMD_PREFIX) OVERLAY=arm64 make recreate-db
.PHONY: wait-for-readiness
wait-for-readiness: # Wait for operators to be ready
$(CMD_PREFIX) ./hack/wait-for-labelled-resource.sh csv --context=$(NEXODUS_KUBE_CONTEXT) -n operators -l operators.coreos.com/cert-manager.operators
$(CMD_PREFIX) ./hack/wait-for-labelled-resource.sh csv --context=$(NEXODUS_KUBE_CONTEXT) -n operators -l operators.coreos.com/prometheus.operators
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) -n operators wait --for=jsonpath='{.status.phase}'=Succeeded csv --all --timeout=5m
$(CMD_PREFIX) ./hack/wait-for-labelled-resource.sh csv --context=$(NEXODUS_KUBE_CONTEXT) -n nexodus-monitoring -l operators.coreos.com/grafana-operator.nexodus-monitoring
$(CMD_PREFIX) kubectl wait --context=$(NEXODUS_KUBE_CONTEXT) -n nexodus-monitoring --for=jsonpath='{.status.phase}'=Succeeded csv --all --timeout=5m
$(CMD_PREFIX) ./hack/wait-for-resource-exists.sh --context=$(NEXODUS_KUBE_CONTEXT) -n ingress-nginx secrets ingress-nginx-admission
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) -n ingress-nginx rollout restart deployment ingress-nginx-controller
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) -n ingress-nginx rollout status deployment ingress-nginx-controller --timeout=5m
.PHONY: deploy
deploy: wait-for-readiness ## Deploy a development nexodus stack onto a kubernetes cluster
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) create namespace nexodus
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) apply -k ./deploy/nexodus/overlays/$(OVERLAY)
$(CMD_PREFIX) OVERLAY=$(OVERLAY) make init-db
$(CMD_PREFIX) $(kubectl) wait --for=condition=Ready pods --all -l app.kubernetes.io/part-of=nexodus --timeout=15m
.PHONY: undeploy
undeploy: ## Remove the nexodus stack from a kubernetes cluster
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) delete namespace nexodus
.PHONY: deploy-monitoring-stack ## Deploy the monitoring stack in the kind cluster
deploy-monitoring-stack:
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) apply -k ./deploy/nexodus-monitoring/overlays/dev
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) -n nexodus-monitoring wait --for=condition=Ready pods --all --timeout=15m
.PHONY: load-images
load-images: ## Load images onto kind
$(CMD_PREFIX) kind load --name nexodus-dev docker-image quay.io/nexodus/apiserver:latest
$(CMD_PREFIX) kind load --name nexodus-dev docker-image quay.io/nexodus/frontend:latest
$(CMD_PREFIX) kind load --name nexodus-dev docker-image quay.io/nexodus/go-ipam:latest
$(CMD_PREFIX) kind load --name nexodus-dev docker-image quay.io/nexodus/envsubst:latest
$(CMD_PREFIX) kind load --name nexodus-dev docker-image quay.io/nexodus/nexd:latest
$(CMD_PREFIX) docker pull docker.io/library/redis:6.0
$(CMD_PREFIX) kind load --name nexodus-dev docker-image docker.io/library/redis:6.0
$(CMD_PREFIX) docker pull docker.io/envoyproxy/envoy:v1.27.0
$(CMD_PREFIX) kind load --name nexodus-dev docker-image docker.io/envoyproxy/envoy:v1.27.0
.PHONY: redeploy
redeploy: images load-images ## Redeploy nexodus after images changes
$(CMD_PREFIX) $(kubectl) rollout restart deploy/apiserver
$(CMD_PREFIX) $(kubectl) rollout restart deploy/frontend
$(CMD_PREFIX) $(kubectl) rollout restart deploy/apiproxy
.PHONY: init-db
init-db:
# wait for the DB to be up, then restart the services that use it.
ifeq ($(OVERLAY),dev)
$(CMD_PREFIX) $(kubectl) wait postgresclusters/database --timeout=15m --for=condition=PGBackRestReplicaRepoReady || true
else ifeq ($(OVERLAY),arm64)
$(CMD_PREFIX) $(kubectl) wait statefulsets/postgres --timeout=15m --for=jsonpath='{.status.readyReplicas}'=1 || true
else ifeq ($(OVERLAY),cockroach)
$(CMD_PREFIX) make deploy-cockroach-operator
$(CMD_PREFIX) $(kubectl) wait --for=condition=Initialized crdbcluster/cockroachdb --timeout=15m
$(CMD_PREFIX) $(kubectl) rollout status statefulsets/cockroachdb --timeout=15m
$(CMD_PREFIX) $(kubectl) exec -it cockroachdb-0 \
-- ./cockroach sql \
--insecure \
--certs-dir=/cockroach/cockroach-certs \
--host=cockroachdb-public \
--execute "\
CREATE DATABASE IF NOT EXISTS ipam;\
CREATE USER IF NOT EXISTS ipam;\
GRANT ALL ON DATABASE ipam TO ipam;\
CREATE DATABASE IF NOT EXISTS apiserver;\
CREATE USER IF NOT EXISTS apiserver;\
GRANT ALL ON DATABASE apiserver TO apiserver;\
CREATE DATABASE IF NOT EXISTS keycloak;\
CREATE USER IF NOT EXISTS keycloak;\
GRANT ALL ON DATABASE keycloak TO keycloak;\
"
endif
$(CMD_PREFIX) $(kubectl) rollout restart deploy/auth
$(CMD_PREFIX) $(kubectl) rollout restart deploy/apiserver
$(CMD_PREFIX) $(kubectl) rollout restart deploy/ipam
$(CMD_PREFIX) $(kubectl) rollout status deploy/auth --timeout=5m
$(CMD_PREFIX) $(kubectl) rollout status deploy/apiserver --timeout=5m
$(CMD_PREFIX) $(kubectl) rollout status deploy/ipam --timeout=5m
.PHONY: recreate-db
recreate-db: ## Delete and bring up a new nexodus database
$(CMD_PREFIX) $(kubectl) delete postgrescluster/database 2> /dev/null || true
$(CMD_PREFIX) $(kubectl) wait --for=delete postgrescluster/database || true
$(CMD_PREFIX) $(kubectl) delete statefulsets/postgres persistentvolumeclaims/postgres-disk-postgres-0 2> /dev/null || true
$(CMD_PREFIX) $(kubectl) wait --for=delete persistentvolumeclaims/postgres-disk-postgres-0
$(CMD_PREFIX) $(kubectl) delete crdbclusters/cockroachdb 2> /dev/null || true
$(CMD_PREFIX) $(kubectl) wait --for=delete --all pods -l app.kubernetes.io/name=cockroachdb --timeout=2m
$(CMD_PREFIX) $(kubectl) delete persistentvolumeclaims/datadir-cockroachdb-0 persistentvolumeclaims/datadir-cockroachdb-1 persistentvolumeclaims/datadir-cockroachdb-2 2> /dev/null || true
$(CMD_PREFIX) $(kubectl) wait --for=delete persistentvolumeclaims/datadir-cockroachdb-0
$(CMD_PREFIX) $(kubectl) wait --for=delete persistentvolumeclaims/datadir-cockroachdb-1
$(CMD_PREFIX) $(kubectl) wait --for=delete persistentvolumeclaims/datadir-cockroachdb-2
$(CMD_PREFIX) kubectl --context=$(NEXODUS_KUBE_CONTEXT) apply -k ./deploy/nexodus/overlays/$(OVERLAY) | grep -v unchanged
$(CMD_PREFIX) OVERLAY=$(OVERLAY) make init-db
$(CMD_PREFIX) $(kubectl) wait --for=condition=Ready pods --all -l app.kubernetes.io/part-of=nexodus --timeout=15m
$(CMD_PREFIX) $(kubectl) rollout restart statefulset redis $(PIPE_DEV_NULL)
$(CMD_PREFIX) $(kubectl) rollout status statefulset redis --timeout=5m
.PHONY: cacerts
cacerts: ## Install the Self-Signed CA Certificate
$(CMD_PREFIX) mkdir -p $(CURDIR)/.certs
$(CMD_PREFIX) $(kubectl) get secret nexodus-ca-key-pair -o json | jq -r '.data."ca.crt"' | base64 -d > $(CURDIR)/.certs/rootCA.pem
$(CMD_PREFIX) CAROOT=$(CURDIR)/.certs mkcert -install
.PHONY: derpcerts
derpcerts: ## Create and fetch the Self-Signed CA Certificate for derp relay from the cluster
@if [ ! -d "$(CURDIR)/.certs" ]; then \
echo ".certs directory does not exist, running make cacerts..."; \
make cacerts; \
fi
$(CMD_PREFIX) ./hack/relayderp-certs.sh
$(CMD_PREFIX) $(kubectl) get secret nexodus-derp-relay-cert -o json | jq -r '.data."tls.crt"' | base64 -d > $(CURDIR)/.certs/relay.nexodus.io.crt
$(CMD_PREFIX) $(kubectl) get secret nexodus-derp-relay-cert -o json | jq -r '.data."tls.key"' | base64 -d > $(CURDIR)/.certs/relay.nexodus.io.key
$(CMD_PREFIX) $(kubectl) get secret nexodus-onboard-derp-relay-cert -o json | jq -r '.data."tls.crt"' | base64 -d > $(CURDIR)/.certs/custom.relay.nexodus.io.crt
$(CMD_PREFIX) $(kubectl) get secret nexodus-onboard-derp-relay-cert -o json | jq -r '.data."tls.key"' | base64 -d > $(CURDIR)/.certs/custom.relay.nexodus.io.key
##@ Packaging
dist/rpm:
$(CMD_PREFIX) mkdir -p dist/rpm
MOCK_ROOTS?=fedora-38-x86_64 fedora-39-x86_64 centos-stream+epel-9-x86_64
MOCK_DEPS:=golang systemd-rpm-macros systemd-units
MOCK_CONTAINER_DEPS?=
.PHONY: image-mock
image-mock: ## Build and publish updated mock images to quay.io used for building rpms
docker build -f Containerfile.mock -t quay.io/nexodus/mock:base .
docker rm -f mock-base
for MOCK_ROOT in $(MOCK_ROOTS) ; do \
docker run --rm --name mock-base --privileged=true -d quay.io/nexodus/mock:base sleep 1800 ; \
for MOCK_DEP in $(MOCK_CONTAINER_DEPS) ; do \
echo "===== Installing $$MOCK_DEP into mock-base" ; \
docker exec -it mock-base dnf install -y $$MOCK_DEP ; \
done ; \
echo "===== Building mock root for $$MOCK_ROOT" ; \
docker exec -it mock-base mock -r $$MOCK_ROOT --init ; \
for MOCK_DEP in $(MOCK_DEPS) ; do \
echo "===== Installing $$MOCK_DEP into $$MOCK_ROOT" ; \
docker exec -it mock-base mock -r $$MOCK_ROOT --no-clean --no-cleanup-after --install $$MOCK_DEP ; \
done ; \
docker commit mock-base quay.io/nexodus/mock:$$(echo $$MOCK_ROOT | cut -f2 -d'+') ; \
docker rm -f mock-base ; \
docker push quay.io/nexodus/mock:$$(echo $$MOCK_ROOT | cut -f2 -d'+') ; \
done
MOCK_ROOTS_AARCH64:=fedora-38-aarch64 fedora-39-aarch64 centos-stream+epel-9-aarch64
.PHONY: image-mock-aarch64
image-mock-aarch64: ## Build and publish updated mock images to quay.io used for building rpms
MOCK_ROOTS="$(MOCK_ROOTS_AARCH64)" MOCK_CONTAINER_DEPS="qemu-user-static-aarch64" $(MAKE) image-mock
MOCK_ROOT?=fedora-39-x86_64
SRPM_MOCK_ROOT?=fedora-39-x86_64
SRPM_DISTRO?=fc39
NEXODUS_AUTORELEASE=0.1.$(shell date -u +%Y%m%d)git$(NEXODUS_RELEASE).$(SRPM_DISTRO)
.PHONY: srpm
srpm: dist/rpm manpages ## Build a source RPM
go mod vendor
rm -rf dist/rpm/nexodus-${NEXODUS_RELEASE}
rm -f dist/rpm/nexodus-${NEXODUS_RELEASE}.tar.gz
git archive --format=tar.gz -o dist/rpm/nexodus-${NEXODUS_RELEASE}.tar.gz --prefix=nexodus-${NEXODUS_RELEASE}/ ${NEXODUS_RELEASE}
cd dist/rpm && tar xzf nexodus-${NEXODUS_RELEASE}.tar.gz
mv vendor dist/rpm/nexodus-${NEXODUS_RELEASE}/.
mkdir -p dist/rpm/nexodus-${NEXODUS_RELEASE}/contrib/man
cp -r contrib/man/* dist/rpm/nexodus-${NEXODUS_RELEASE}/contrib/man/.
NEXODUS_BUILD_PROFILE=prod $(MAKE) ldflags.txt
mv ldflags.txt dist/rpm/nexodus-${NEXODUS_RELEASE}/.
cd dist/rpm && tar czf nexodus-${NEXODUS_RELEASE}.tar.gz nexodus-${NEXODUS_RELEASE} && rm -rf nexodus-${NEXODUS_RELEASE}
cp contrib/rpm/nexodus.spec.in contrib/rpm/nexodus.spec
sed -i -e "s/##NEXODUS_COMMIT##/${NEXODUS_RELEASE}/" contrib/rpm/nexodus.spec
sed -i -e "s/##NEXODUS_AUTORELEASE##/$(NEXODUS_AUTORELEASE)/" contrib/rpm/nexodus.spec
docker run --name mock --rm --privileged=true -v $(CURDIR):/nexodus quay.io/nexodus/mock:$$(echo $(SRPM_MOCK_ROOT) | cut -f2 -d'+') \
mock --buildsrpm -D "_commit ${NEXODUS_RELEASE}" --resultdir=/nexodus/dist/rpm/mock --no-clean --no-cleanup-after \
--spec /nexodus/contrib/rpm/nexodus.spec --sources /nexodus/dist/rpm/ --root ${SRPM_MOCK_ROOT}
rm -f dist/rpm/nexodus-${NEXODUS_RELEASE}.tar.gz
.PHONY: rpm
rpm: srpm ## Build an RPM
docker run --name mock --rm --privileged=true -v $(CURDIR):/nexodus quay.io/nexodus/mock:$$(echo $(MOCK_ROOT) | cut -f2 -d'+') \
mock --rebuild --without check --resultdir=/nexodus/dist/rpm/mock --root ${MOCK_ROOT} \
--no-clean --no-cleanup-after --enable-network \
/nexodus/$(wildcard dist/rpm/mock/nexodus-0-0.1.$(shell date -u +%Y%m%d)git$(NEXODUS_RELEASE).$(SRPM_DISTRO).src.rpm)
.PHONY: version
version: ## Print the version string
$(CMD_PREFIX) echo "${NEXODUS_VERSION}-${NEXODUS_RELEASE}"
ldflags.txt:
@echo "$(NEXODUS_LDFLAGS) " > ldflags.txt
##@ Documentation
contrib/man:
$(CMD_PREFIX) mkdir -p contrib/man
.PHONY: manpages
manpages: contrib/man dist/nexd dist/nexctl ## Generate manpages in ./contrib/man
dist/nexd -h | docker run -i --rm --name txt2man quay.io/nexodus/mock:$$(echo $(MOCK_ROOT) | cut -f2 -d'+') txt2man -t nexd | gzip > contrib/man/nexd.8.gz
dist/nexctl -h | docker run -i --rm --name txt2man quay.io/nexodus/mock:$$(echo $(MOCK_ROOT) | cut -f2 -d'+') txt2man -t nexctl | gzip > contrib/man/nexctl.8.gz
# Nothing to see here
.PHONY: cat
cat:
$(CMD_PREFIX) docker run -it --rm --name nyancat 06kellyjac/nyancat@sha256:571396596a0b9367abb72c52619abcbc5b31f766720b181040a33aa959ebfba1
.PHONY: docs
docs: ## Generate docs site into site/ directory
$(CMD_PREFIX) docker run --rm -it -v ${PWD}:/docs $(MKDOCS_MATERIAL_IMAGE) build
.PHONY: docs-preview
docs-preview: ## Generate a live preview of project documentation
$(CMD_PREFIX) docker run --rm -it -p 8000:8000 -v ${PWD}:/docs $(MKDOCS_MATERIAL_IMAGE)
.PHONY: graph-prereqs
graph-prereqs:
$(CMD_PREFIX) if ! which godepgraph >/dev/null 2>&1; then \
echo "Please install godepgraph:" ; \
echo " go install github.com/kisielk/godepgraph@latest"; \
exit 1 ; \
fi
$(CMD_PREFIX) if ! which dot >/dev/null 2>&1; then \
echo "Please install Graphviz." ; \
echo "See: https://graphviz.org/download/" ; \
exit 1 ; \
fi
.PHONY: graph-all
graph-all: graph-nexd graph-nexctl graph-apiserver ## Graph the package dependencies of the binaries
graph-%: graph-prereqs
@mkdir dist || true
$(ECHO_PREFIX) printf " %-12s dist/graph-$(word 2,$(subst -, ,$@)).png\n" "[GRAPHING]"
$(CMD_PREFIX) godepgraph -s ./cmd/$(word 2,$(subst -, ,$@)) | dot -Tpng -o dist/graph-$(word 2,$(subst -, ,$@)).png