diff --git a/.gitignore b/.gitignore index 492b4e0..1e8cedf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ bin/ .idea/ cover.out -golangci-lint \ No newline at end of file +golangci-lint +.DS_Store \ No newline at end of file diff --git a/.moia-mk.lock b/.moia-mk.lock new file mode 100644 index 0000000..86dd09a --- /dev/null +++ b/.moia-mk.lock @@ -0,0 +1 @@ +v0.15.0 diff --git a/mk-templates/assets/ecr.yml b/mk-templates/assets/ecr.yml new file mode 100644 index 0000000..1d269a6 --- /dev/null +++ b/mk-templates/assets/ecr.yml @@ -0,0 +1,88 @@ +--- +AWSTemplateFormatVersion: "2010-09-09" +Description: "An ECR repository" +Parameters: + RepositoryName: + Type: String + Description: Name of the ECR repository. +Resources: + Repository: + Type: "AWS::ECR::Repository" + Properties: + RepositoryName: !Ref "RepositoryName" + ImageScanningConfiguration: + scanOnPush: true + LifecyclePolicy: + LifecyclePolicyText: | + { + "rules": [ + { + "rulePriority": 1, + "description": "Keep at minimum 50 prd images", + "selection": { + "tagStatus": "tagged", + "tagPrefixList": ["prd"], + "countType": "imageCountMoreThan", + "countNumber": 50 + }, + "action": { + "type": "expire" + } + }, + { + "rulePriority": 2, + "description": "Keep at minimum 50 int images", + "selection": { + "tagStatus": "tagged", + "tagPrefixList": ["int"], + "countType": "imageCountMoreThan", + "countNumber": 50 + }, + "action": { + "type": "expire" + } + }, + { + "rulePriority": 3, + "description": "Keep at minimum 50 dev images", + "selection": { + "tagStatus": "tagged", + "tagPrefixList": ["dev"], + "countType": "imageCountMoreThan", + "countNumber": 50 + }, + "action": { + "type": "expire" + } + }, + { + "rulePriority": 4, + "description": "Keep only 200 images, expire all others (except those marked with dev, int, prd)", + "selection": { + "tagStatus": "any", + "countType": "imageCountMoreThan", + "countNumber": 200 + }, + "action": { + "type": "expire" + } + } + ] + } + RepositoryPolicyText: + Version: "2012-10-17" + Statement: + - Sid: allowK8s + Effect: Allow + Principal: + AWS: + - "*" + Action: + - "ecr:GetDownloadUrlForLayer" + - "ecr:BatchGetImage" + - "ecr:BatchCheckLayerAvailability" + Condition: + ForAnyValue:StringLike: + aws:PrincipalOrgPaths: + - "o-h4a0f4tabz/r-xg0k/ou-xg0k-29qckrwr/*" + - "o-h4a0f4tabz/r-xg0k/ou-xg0k-4hgab4ao/*" diff --git a/mk-templates/assets/golangci.yml b/mk-templates/assets/golangci.yml index e57df9a..e3eee18 100644 --- a/mk-templates/assets/golangci.yml +++ b/mk-templates/assets/golangci.yml @@ -2,15 +2,15 @@ # https://github.com/golangci/golangci/wiki/Configuration service: # use the fixed version to not introduce new linters unexpectedly - golangci-lint-version: 1.49.x + golangci-lint-version: 1.54.x run: # golang-ci lint runtime timeout deadline: 5m # moias latest supported Go version - go: "1.20" + go: "1.22" # see: https://golangci-lint.run/usage/configuration/ - modules-download-mode: vendor + modules-download-mode: readonly # include test files or not. tests: false @@ -26,8 +26,6 @@ linters: - whitespace # godot checks if all top-level comments contain a period at the end of the last sentence if needed. - godot - # depguard to make sure import paths specific are required - - depguard # gocyclo calculates cyclomatic complexities of functions in Go source code. - gocyclo # gosec inspects source code for security problems by scanning the Go AST. @@ -47,14 +45,6 @@ issues: - errcheck linters-settings: - # depguard settings - depguard: - list-type: blacklist - include-go-root: true - # error on the following import paths: - packages-with-error-message: - - github.com/stretchr/testify/assert: "Use github.com/stretchr/testify/require instead of github.com/stretchr/testify/assert" - - github.com/pkg/errors: "Use fmt or errors instead of github.com/pkg/errors" # gofumpt settings gofumpt: extra-rules: true diff --git a/mk-templates/common.mk b/mk-templates/common.mk new file mode 100644 index 0000000..3a5ec09 --- /dev/null +++ b/mk-templates/common.mk @@ -0,0 +1,39 @@ +# This make target makes environment variables mandatory + +ssm-get = $(shell aws ssm get-parameter --name '$(1)' --with-decryption --region '$(AWS_REGION)' --query 'Parameter.Value' --output text) + +aws-vpc-link-id = $(shell aws apigateway get-vpc-links | jq '.items[] | select(.name == "$(MOIA_ENVIRONMENT)-inlb-link") | .id') + +# To properly use this, you need to add guard-{YOUR_ENV_VAR} as a dependency +# to your make target. +# Example: +# Consider you want to make MOIA_ENVIRONMENT mandatory for your deploy make +# target. You then need to add the following line to your deploy target: +# deploy: guard-MOIA_ENVIRONMENT +# ... +# +# There is also a special case for MOIA_ENVIRONMENT. If we have a kubernetes +# context, we check if the name of environment in the cluster name is the same +# otherwise we abort as well, because the wrong env will probably be applied in +# the wrong cluster +guard-%: + @if [ $* = "MOIA_ENVIRONMENT" ]; then \ + if [ -x "$$(command -v kubectl)" ]; then \ + cluster="$$(kubectl cluster-info 2>/dev/null | head -n1 | awk '{print $$NF}' | sed $$'s,\x1b\\[[0-9;]*[a-zA-Z],,g')"; \ + env="$$(echo "$$cluster" | sed 's/^https\:\/\/api\.cluster\.trip\.\([a-z][a-z]*\)\.moia\-group\.io$$/\1/')"; \ + if [ -n "$$cluster" ] && [ -z "$$env" ]; then \ + echo "Couldn't determine the environment from the cluster URL: $$cluster"; \ + exit 2; \ + fi; \ + if [ "$$env" = "poc" ] || [ "$$env" = "dev" ] || [ "$$env" = "int" ] || [ "$$env" = "prd" ]; then \ + if [ "$$env" != "$$MOIA_ENVIRONMENT" ]; then \ + echo "Cluster name is $$cluster, but MOIA_ENVIRONMENT is $$MOIA_ENVIRONMENT. Aborting..."; \ + exit 1; \ + fi \ + fi \ + fi \ + fi; \ + if [ "${${*}}" = "" ]; then \ + echo "Environment variable $* not set"; \ + exit 1; \ + fi diff --git a/mk-templates/docker.mk b/mk-templates/docker.mk index 93d174f..b5ceb9c 100644 --- a/mk-templates/docker.mk +++ b/mk-templates/docker.mk @@ -1,13 +1,16 @@ +SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(SELF_DIR)/common.mk + DOCKER_REGISTRY ?= 614608043005.dkr.ecr.eu-central-1.amazonaws.com DOCKER_IMAGE_TAG ?= latest DOCKER_FILE ?= Dockerfile DOCKER_AWS_REGION ?= eu-central-1 .PHONY: docker-build -docker-build: +docker-build: guard-SERVICE guard-DOCKER_REGISTRY docker build --no-cache -t $(DOCKER_REGISTRY)/$(SERVICE):$(DOCKER_IMAGE_TAG) -f $(DOCKER_FILE) . .PHONY: push-image -push-image: docker-build +push-image: guard-SERVICE guard-DOCKER_REGISTRY docker-build aws ecr get-login-password --region $(DOCKER_AWS_REGION) | docker login --username AWS --password-stdin $(DOCKER_REGISTRY) docker push $(DOCKER_REGISTRY)/$(SERVICE):$(DOCKER_IMAGE_TAG) diff --git a/mk-templates/ecr.mk b/mk-templates/ecr.mk new file mode 100644 index 0000000..1977eb1 --- /dev/null +++ b/mk-templates/ecr.mk @@ -0,0 +1,14 @@ +SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(SELF_DIR)/common.mk + +AWS_REGION ?= eu-central-1 + +.PHONY: ecr +ecr: guard-SERVICE guard-AWS_REGION +ecr: ${SELF_DIR}/assets/ecr.yml + aws cloudformation deploy \ + --no-fail-on-empty-changeset \ + --template-file $< \ + --stack-name $(SERVICE)-ecr \ + --parameter-overrides RepositoryName=$(SERVICE) \ + --region $(AWS_REGION) diff --git a/mk-templates/github.mk b/mk-templates/github.mk new file mode 100644 index 0000000..a0c9b44 --- /dev/null +++ b/mk-templates/github.mk @@ -0,0 +1,34 @@ +# this makefile can be used to create a Github Release in a repository, with all binaries for +# linux and darwin as seperate applications +GITHUB_OWNER = moia-dev +GITHUB_REPOSITORY = $(shell basename `git rev-parse --show-toplevel`) + +ifdef GIT_VERSION + VERSION = ${GIT_VERSION} +else + VERSION = $(shell git describe --always --tags --dirty) +endif + +# we need to do some magic here, because importing this will not work when we are not +# in this folder, e.g. from ../ the include will fail-- make is not smart. +# +# the last word of the MAKEFILE_LIST is the current makefile, so we can take that +# and append it to the include directory so that it will always be accurate +# +# not that you cannot use make -f with this approach, and must run the make targets +# in the same directory as the Makefile +SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(SELF_DIR)/common.mk + +.PHONY: release-dependencies +release-dependencies: + go get -u github.com/aktau/github-release + +.PHONY: release +release: guard-VERSION release-dependencies + $(if $(GITHUB_TOKEN),,$(eval GITHUB_TOKEN=$(call ssm-get,/Github/ApiToken))) + github-release info --user $(GITHUB_OWNER) --repo $(GITHUB_REPOSITORY) -s $(GITHUB_TOKEN) + github-release release --user $(GITHUB_OWNER) --repo $(GITHUB_REPOSITORY) --tag $(VERSION) --name $(VERSION) -s $(GITHUB_TOKEN) + for f in bin/linux_amd64/*; do github-release upload --user $(GITHUB_OWNER) --repo $(GITHUB_REPOSITORY) -s $(GITHUB_TOKEN) --tag $(VERSION) --name `basename $${f}`_linux_amd64 --file $${f}; done + for f in bin/darwin_amd64/*; do github-release upload --user $(GITHUB_OWNER) --repo $(GITHUB_REPOSITORY) -s $(GITHUB_TOKEN) --tag $(VERSION) --name `basename $${f}`_darwin_amd64 --file $${f}; done + github-release edit --user $(GITHUB_OWNER) --repo $(GITHUB_REPOSITORY) -s $(GITHUB_TOKEN) --tag $(VERSION) --name $(VERSION) --description $(VERSION) diff --git a/mk-templates/go.mk b/mk-templates/go.mk index 9aaa769..8c8b3e9 100644 --- a/mk-templates/go.mk +++ b/mk-templates/go.mk @@ -4,15 +4,21 @@ SYSTEM := $(shell uname -s | tr A-Z a-z)_$(shell uname -m | sed " GO_PREFIX := CGO_ENABLED=0 GOFLAGS=-mod=vendor GOPRIVATE=github.com/moia-dev GO := $(GO_PREFIX) go # This collects every path, which contains go files in the current project +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Linux) LINT_TARGETS := $(shell find -name '*.go' | sed -e "s|\(.*\)/.*\.go\$$|\1/...|g" | grep -v vendor | grep -v node_modules | uniq) +endif +ifeq ($(UNAME_S),Darwin) +LINT_TARGETS := $(shell find . -name '*.go' | sed -e "s|\(.*\)/.*\.go\$$|\1/...|g" | grep -v vendor | grep -v node_modules | uniq) +endif # The current version of golangci-lint. # See: https://github.com/golangci/golangci-lint/releases -GOLANGCI_LINT_VERSION ?= 1.51.2 +GOLANGCI_LINT_VERSION ?= 1.56.2 # Executes the linter on all our go files inside of the project .PHONY: lint create-golint-config lint: bin/golangci-lint-$(GOLANGCI_LINT_VERSION) - $(GO_PREFIX) ./bin/golangci-lint-$(GOLANGCI_LINT_VERSION) --timeout 120s run $(LINT_TARGETS) + $(GO_PREFIX) ./bin/golangci-lint-$(GOLANGCI_LINT_VERSION) --timeout 240s run $(LINT_TARGETS) .PHONY: create-golint-config create-golint-config: diff --git a/mk-templates/jsonnet.mk b/mk-templates/jsonnet.mk new file mode 100644 index 0000000..f38a4ad --- /dev/null +++ b/mk-templates/jsonnet.mk @@ -0,0 +1,15 @@ +SYSTEM := $(shell uname -s | tr A-Z a-z)_$(shell uname -m | sed "s/x86_64/amd64/") +# The current version of the jsonnet-bundler +# See: https://github.com/jsonnet-bundler/jsonnet-bundler/releases +JB_VERSION := 0.4.0 + +.PHONY: bin/jb +bin/jb: bin/jb-$(JB_VERSION) + +# Downloads the current jsonnet-bundler executable into the bin directory and +# makes it executable +bin/jb-$(JB_VERSION): + mkdir -p bin + curl -sSLf \ + https://github.com/jsonnet-bundler/jsonnet-bundler/releases/download/v$(JB_VERSION)/jb-$(shell echo $(SYSTEM) | tr '_' '-') \ + -o $@ && chmod +x $@ && ln -s $@ bin/jb