Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .custom-gcl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: v2.6.2
name: golangci-lint-kube-api-linter
destination: ./bin
plugins:
- module: 'sigs.k8s.io/kube-api-linter'
version: v0.0.0-20251112164541-d94382a24f06
6 changes: 5 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ jobs:
uses: golangci/golangci-lint-action@v7
with:
install-mode: goinstall
version: v2.0.2
version: v2.6.2

- name: Run ShellCheck
uses: ludeeus/action-shellcheck@master

- name: Running nilaway
run: |
make lint-nilaway

- name: Running golang-ci-lint-kube-api-linter
run: |
make lint-api
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ dist/*
# e2e files
_artifacts
*-envsubst.yaml
test/e2e/data/infrastructure-scaleway/v1beta1/*.yaml
test/e2e/data/infrastructure-scaleway/v1beta2/*.yaml
80 changes: 80 additions & 0 deletions .golangci-kal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
version: "2"
run:
go: "1.24"
allow-parallel-runners: true
linters:
default: none
enable:
- kubeapilinter # linter for Kube API conventions
settings:
custom:
kubeapilinter:
type: module
description: KAL is the Kube-API-Linter and lints Kube like APIs based on API conventions and best practices.
settings:
linters:
enable:
- "commentstart" # Ensure comments start with the serialized version of the field name.
- "conditions" # Ensure conditions have the correct json tags and markers.
- "conflictingmarkers"
- "duplicatemarkers" # Ensure there are no exact duplicate markers. for types and fields.
#- "forbiddenmarkers" # Ensure that types and fields do not contain any markers that are forbidden.
- "integers" # Ensure only int32 and int64 are used for integers.
- "jsontags" # Ensure every field has a json tag.
- "maxlength" # Ensure all strings and arrays have maximum lengths/maximum items.
#- "nobools" # Bools do not evolve over time, should use enums instead.
- "nodurations" # Prevents usage of `Duration` types.
- "nofloats" # Ensure floats are not used.
- "nomaps" # Ensure maps are not used.
- "nonullable" # Ensure that types and fields do not have the nullable marker.
- "nophase" # Phase fields are discouraged by the Kube API conventions, use conditions instead.
- "notimestamp" # Prevents usage of 'Timestamp' fields
- "optionalfields" # Ensure that all fields marked as optional adhere to being pointers and
# having the `omitempty` value in their `json` tag where appropriate.
- "optionalorrequired" # Every field should be marked as `+optional` or `+required`.
- "requiredfields" # Required fields should not be pointers, and should not have `omitempty`.
- "ssatags" # Ensure array fields have the appropriate listType markers
- "statusoptional" # Ensure all first children within status should be optional.
- "statussubresource" # All root objects that have a `status` field should have a status subresource.
- "uniquemarkers" # Ensure that types and fields do not contain more than a single definition of a marker that should only be present once.

# Linters below this line are disabled, pending conversation on how and when to enable them.
disable:
- "*" # We will manually enable new linters after understanding the impact. Disable all by default.
lintersConfig:
conflictingmarkers:
conflicts:
- name: "default_vs_required"
sets:
- ["default", "kubebuilder:default"]
- ["required", "kubebuilder:validation:Required", "k8s:required"]
description: "A field with a default value cannot be required"
conditions:
isFirstField: Warn # Require conditions to be the first field in the status struct.
usePatchStrategy: Forbid # Forbid patchStrategy markers on the Conditions field.
useProtobuf: Forbid # We don't use protobuf, so protobuf tags are not required.
optionalfields:
pointers:
preference: WhenRequired # Always | WhenRequired # Whether to always require pointers, or only when required. Defaults to `Always`.
policy: SuggestFix # SuggestFix | Warn # The policy for pointers in optional fields. Defaults to `SuggestFix`.
omitempty:
policy: SuggestFix # SuggestFix | Warn | Ignore # The policy for omitempty in optional fields. Defaults to `SuggestFix`.

exclusions:
generated: strict
paths:
- zz_generated.*\.go$
- ".*_test.go" # Exclude test files.
rules:
## KAL should only run on API folders.
- path-except: "api//*"
linters:
- kubeapilinter

## Excludes for old apiVersions that can be removed once the apiVersions are dropped (we don't want to make any changes to these APIs).
- path: "api/v1alpha1"
linters:
- kubeapilinter
issues:
max-same-issues: 0
max-issues-per-linter: 0
25 changes: 19 additions & 6 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,34 @@ linters:
alias:
- pkg: sigs.k8s.io/controller-runtime/pkg/log
alias: logf
- pkg: sigs.k8s.io/cluster-api/api/v1beta1
- pkg: sigs.k8s.io/cluster-api/api/core/v1beta2
alias: clusterv1
- pkg: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha1
- pkg: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha2
alias: infrav1
- pkg: k8s.io/apimachinery/pkg/api/errors
alias: apierrors
- pkg: k8s.io/apimachinery/pkg/util/errors
alias: utilerrors
- pkg: github.com/scaleway/cluster-api-provider-scaleway/internal/service/scaleway/lb/util
alias: lbutil
- pkg: k8s.io/apimachinery/pkg/apis/meta/v1
alias: metav1
exclusions:
generated: lax
rules:
- linters:
- lll
path: api/*
- linters:
- lll
path: cmd/main.go
- linters:
- lll
path: test/e2e/*
- linters:
- dupl
- lll
path: internal/*
- linters:
- staticcheck
text: "ST1019"
- linters:
- staticcheck
text: "ST1005"
Expand All @@ -73,11 +75,22 @@ linters:
- examples$
formatters:
enable:
- gci
- gofmt
- goimports
settings:
gci:
sections:
- standard
- blank
- dot
- default
- localmodule
custom-order: true
exclusions:
generated: lax
generated: strict
paths:
- zz_generated.*\.go$
- third_party$
- builtin$
- examples$
44 changes: 33 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ else
GOBIN=$(shell go env GOBIN)
endif

TOOLS_DIR := hack/tools
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

# CONTAINER_TOOL defines the container tool to be used for building images.
Expand Down Expand Up @@ -48,10 +49,14 @@ manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and Cust
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases

.PHONY: generate
generate: controller-gen mockgen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
generate: controller-gen generate-go-conversions mockgen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(CONTROLLER_GEN) object paths="./..."
go generate ./...

.PHONY: generate-go-conversions
generate-go-conversions: conversion-gen ## Generate conversions go code
$(CONVERSION_GEN) --output-file=zz_generated.conversion.go github.com/scaleway/cluster-api-provider-scaleway/api/...

.PHONY: fmt
fmt: ## Run go fmt against code.
go fmt ./...
Expand All @@ -70,7 +75,7 @@ KIND_KUBECONFIG ?= /tmp/caps-e2e-kubeconfig
E2E_ARTIFACTS ?= $(ROOT_DIR)/_artifacts
E2E_CONF_FILE ?= $(ROOT_DIR)/test/e2e/config/scaleway.yaml
E2E_CONF_FILE_ENVSUBST := $(ROOT_DIR)/test/e2e/config/scaleway-envsubst.yaml
E2E_V1BETA1_TEMPLATES := $(ROOT_DIR)/test/e2e/data/infrastructure-scaleway/v1beta1
E2E_V1BETA2_TEMPLATES := $(ROOT_DIR)/test/e2e/data/infrastructure-scaleway/v1beta2
E2E_FOCUS ?= ""

.PHONY: setup-test-e2e
Expand All @@ -83,9 +88,9 @@ setup-test-e2e: ## Set up a Kind cluster for e2e tests if it does not exist

.PHONY: generate-e2e
generate-e2e: kustomize ## Generate templates for e2e
$(KUSTOMIZE) build $(E2E_V1BETA1_TEMPLATES)/cluster-template --load-restrictor LoadRestrictionsNone > $(E2E_V1BETA1_TEMPLATES)/cluster-template.yaml
$(KUSTOMIZE) build $(E2E_V1BETA1_TEMPLATES)/cluster-template-private-network --load-restrictor LoadRestrictionsNone > $(E2E_V1BETA1_TEMPLATES)/cluster-template-private-network.yaml
$(KUSTOMIZE) build $(E2E_V1BETA1_TEMPLATES)/cluster-template-managed --load-restrictor LoadRestrictionsNone > $(E2E_V1BETA1_TEMPLATES)/cluster-template-managed.yaml
$(KUSTOMIZE) build $(E2E_V1BETA2_TEMPLATES)/cluster-template --load-restrictor LoadRestrictionsNone > $(E2E_V1BETA2_TEMPLATES)/cluster-template.yaml
$(KUSTOMIZE) build $(E2E_V1BETA2_TEMPLATES)/cluster-template-private-network --load-restrictor LoadRestrictionsNone > $(E2E_V1BETA2_TEMPLATES)/cluster-template-private-network.yaml
$(KUSTOMIZE) build $(E2E_V1BETA2_TEMPLATES)/cluster-template-managed --load-restrictor LoadRestrictionsNone > $(E2E_V1BETA2_TEMPLATES)/cluster-template-managed.yaml

.PHONY: test-e2e
test-e2e: setup-test-e2e generate-e2e docker-build envsubst ginkgo build-installer fmt vet ## Run the e2e tests. Expected an isolated environment using Kind.
Expand All @@ -101,13 +106,17 @@ cleanup-test-e2e: ## Tear down the Kind cluster used for e2e tests
@$(KIND) delete cluster --name $(KIND_CLUSTER) --kubeconfig $(KIND_KUBECONFIG)

.PHONY: lint
lint: lint-golangci-lint lint-nilaway ## Run linters
lint: lint-api lint-golangci-lint lint-nilaway ## Run linters
@echo "done"

.PHONY: lint-golangci-lint
lint-golangci-lint: golangci-lint ## Run golangci-lint linter
$(GOLANGCI_LINT) run

.PHONY: lint-api
lint-api: golangci-lint-kube-api-linter ## Run golangci-lint-kube-api-linter linter
$(GOLANGCI_LINT_KAL) run --config .golangci-kal.yml

.PHONY: lint-nilaway
lint-nilaway: nilaway ## Run nilaway linter
$(NILAWAY) -include-pkgs=github.com/scaleway/cluster-api-provider-scaleway ./...
Expand Down Expand Up @@ -217,19 +226,22 @@ NILAWAY = $(LOCALBIN)/nilaway
MOCKGEN = $(LOCALBIN)/mockgen
ENVSUBST = $(LOCALBIN)/envsubst
GINKGO = $(LOCALBIN)/ginkgo
GOLANGCI_LINT_KAL := $(LOCALBIN)/golangci-lint-kube-api-linter
CONVERSION_GEN ?= $(LOCALBIN)/conversion-gen

## Tool Versions
KUSTOMIZE_VERSION ?= v5.6.0
CONTROLLER_TOOLS_VERSION ?= v0.18.0
KUSTOMIZE_VERSION ?= v5.7.1
CONTROLLER_TOOLS_VERSION ?= v0.19.0
#ENVTEST_VERSION is the version of controller-runtime release branch to fetch the envtest setup script (i.e. release-0.20)
ENVTEST_VERSION ?= $(shell go list -m -f "{{ .Version }}" sigs.k8s.io/controller-runtime | awk -F'[v.]' '{printf "release-%d.%d", $$2, $$3}')
#ENVTEST_K8S_VERSION is the version of Kubernetes to use for setting up ENVTEST binaries (i.e. 1.31)
ENVTEST_K8S_VERSION ?= $(shell go list -m -f "{{ .Version }}" k8s.io/api | awk -F'[v.]' '{printf "1.%d", $$3}')
GOLANGCI_LINT_VERSION ?= v2.1.0
GOLANGCI_LINT_VERSION ?= v2.6.2
NILAWAY_VERSION ?= latest
MOCKGEN_VERSION ?= v0.5.2
MOCKGEN_VERSION ?= v0.6.0
ENVSUBST_VERSION ?=latest
GINKGO_VERSION ?= v2.23.4
GINKGO_VERSION ?= v2.25.3
CONVERSION_GEN_VERSION ?= v0.34.0

.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
Expand All @@ -241,6 +253,11 @@ controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessar
$(CONTROLLER_GEN): $(LOCALBIN)
$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION))

.PHONY: conversion-gen
conversion-gen: $(CONVERSION_GEN) ## Download conversion-gen locally if necessary.
$(CONVERSION_GEN): $(LOCALBIN)
$(call go-install-tool,$(CONVERSION_GEN),k8s.io/code-generator/cmd/conversion-gen,$(CONVERSION_GEN_VERSION))

.PHONY: setup-envtest
setup-envtest: envtest ## Download the binaries required for ENVTEST in the local bin directory.
@echo "Setting up envtest binaries for Kubernetes version $(ENVTEST_K8S_VERSION)..."
Expand Down Expand Up @@ -279,6 +296,11 @@ ginkgo: $(GINKGO) ## Download ginkgo locally if necessary.
$(GINKGO): $(LOCALBIN)
$(call go-install-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo,$(GINKGO_VERSION))

.PHONY: golangci-lint-kube-api-linter
golangci-lint-kube-api-linter: $(GOLANGCI_LINT_KAL) ## Build golangci-lint-kal from custom configuration.
$(GOLANGCI_LINT_KAL): $(GOLANGCI_LINT)
$(GOLANGCI_LINT) custom

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary
# $2 - package url which can be installed
Expand Down
92 changes: 92 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,96 @@ resources:
kind: ScalewayManagedMachinePool
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
domain: cluster.x-k8s.io
group: infrastructure
kind: ScalewayCluster
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha2
version: v1alpha2
webhooks:
conversion: true
spoke:
- v1alpha1
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: cluster.x-k8s.io
group: infrastructure
kind: ScalewayMachine
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha2
version: v1alpha2
webhooks:
conversion: true
spoke:
- v1alpha1
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: cluster.x-k8s.io
group: infrastructure
kind: ScalewayClusterTemplate
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha2
version: v1alpha2
webhooks:
conversion: true
spoke:
- v1alpha1
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: cluster.x-k8s.io
group: infrastructure
kind: ScalewayMachineTemplate
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha2
version: v1alpha2
webhooks:
conversion: true
spoke:
- v1alpha1
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: cluster.x-k8s.io
group: infrastructure
kind: ScalewayManagedCluster
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha2
version: v1alpha2
webhooks:
conversion: true
spoke:
- v1alpha1
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: cluster.x-k8s.io
group: infrastructure
kind: ScalewayManagedControlPlane
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha2
version: v1alpha2
webhooks:
conversion: true
defaulting: true
spoke:
- v1alpha1
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: cluster.x-k8s.io
group: infrastructure
kind: ScalewayManagedMachinePool
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha2
version: v1alpha2
webhooks:
conversion: true
spoke:
- v1alpha1
webhookVersion: v1
version: "3"
Loading