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
22 changes: 22 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Build
on:
push:
pull_request:

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
cache: false

- name: Build
run: make
18 changes: 16 additions & 2 deletions .github/workflows/lint.yaml → .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Lint
name: CI
on:
push:
pull_request:
Expand All @@ -8,8 +8,8 @@ permissions:

jobs:
lint:
name: lint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

Expand All @@ -23,3 +23,17 @@ jobs:
with:
version: v2.3
args: '--timeout=10m'

test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
cache: false

- name: Tests
run: make test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ go.work
*.swo
*~
.tiltbuild
.envtest

out/
56 changes: 18 additions & 38 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,28 @@ run:
allow-parallel-runners: true

linters:
default: none
enable:
- bodyclose
- dupl
- errcheck
- errname
- exhaustive
- goconst
- gocritic
- goprintffuncname
- gosec
- govet
- ineffassign
- misspell
- nakedret
- nilerr
- noctx
- prealloc
- rowserrcheck
- sqlclosecheck
- staticcheck
- unconvert
- unparam
- unused
- wastedassign
- whitespace
settings:
goconst:
min-len: 2
min-occurrences: 2
gocritic:
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
gocyclo:
min-complexity: 10
misspell:
locale: US
# - wsl_v5
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- gochecknoglobals
Expand All @@ -62,18 +36,24 @@ linters:
- staticcheck
- unparam
path: _test\.go
paths:
- third_party$
- builtin$
- examples$

formatters:
enable:
- gci
- gofmt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
- gofumpt
settings:
gci:
# The default order is `standard > default > custom > blank > dot > alias > localmodule`.
custom-order: true
sections:
- standard
- default
- alias
- localmodule
- dot
- blank
gofmt:
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
31 changes: 11 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,11 @@ generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and

.PHONY: fmt
fmt: ## Run go fmt against code.
go fmt ./...

.PHONY: vet
vet: ## Run go vet against code.
go vet ./...
$(GOLANGCI_LINT) fmt ./...

.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out

# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up.
test-e2e:
go test ./test/e2e/ -v -ginkgo.v
test: manifests generate ## Run tests.
go test -v -coverprofile cover.out $$(go list ./... | grep -v /e2e)

.PHONY: lint
lint: ## Run golangci-lint linter & yamllint
Expand All @@ -84,11 +75,11 @@ lint-fix: ## Run golangci-lint linter and perform fixes
##@ Build

.PHONY: build
build: manifests generate fmt vet ## Build manager binary.
build: manifests generate ## Build manager binary.
go build -o bin/manager cmd/main.go

.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
run: manifests generate ## Run a controller from your host.
go run ./cmd/main.go

# If you wish to build the manager image targeting other platforms you can use the --platform flag.
Expand Down Expand Up @@ -186,25 +177,25 @@ $(LOCALBIN):
GOLANGCI_LINT_VERSION ?= v2.3.0
KUSTOMIZE_VERSION ?= v5.3.0
CONTROLLER_TOOLS_VERSION ?= v0.14.0
ENVTEST_VERSION ?= latest
ENVTEST_VERSION ?= v0.0.0-20250505003155-b6c5897febe5
ENVTEST_K8S_VERSION := 1.31.0

KUBECTL ?= kubectl
GOLANGCI_LINT ?= go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
KUSTOMIZE ?= go run sigs.k8s.io/kustomize/kustomize/v5@$(KUSTOMIZE_VERSION)

ENVTEST ?= go run sigs.k8s.io/controller-runtime/tools/setup-envtest@$(ENVTEST_VERSION)
ENVTEST_DIR ?= $(shell pwd)/.envtest
export KUBEBUILDER_ASSETS ?= $(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(ENVTEST_DIR) -p path)

## Tool Binaries
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen-$(CONTROLLER_TOOLS_VERSION)
ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION)

.PHONY: controller-gen
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
$(CONTROLLER_GEN): $(LOCALBIN)
$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION))

.PHONY: envtest
envtest: $(ENVTEST) ## Download setup-envtest locally if necessary.
$(ENVTEST): $(LOCALBIN)
$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION))

# 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 (ideally with version)
Expand Down
16 changes: 8 additions & 8 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,29 @@ import (

"github.com/go-logr/stdr"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/discovery/cached/memory"
"k8s.io/client-go/kubernetes"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/webhook"

upstream "github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
clusterv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"

controlplanev1alpha1 "github.com/rancher/cluster-api-provider-k3k/api/controlplane/v1alpha1"
infrastructurev1alpha1 "github.com/rancher/cluster-api-provider-k3k/api/infrastructure/v1alpha1"
controlplanecontroller "github.com/rancher/cluster-api-provider-k3k/internal/controller/controlplane"
infrastructurecontroller "github.com/rancher/cluster-api-provider-k3k/internal/controller/infrastructure"
"github.com/rancher/cluster-api-provider-k3k/internal/helm"
//+kubebuilder:scaffold:imports

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"
)

var (
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.24.2
require (
github.com/go-logr/logr v1.4.3
github.com/go-logr/stdr v1.2.2
github.com/onsi/gomega v1.36.0
github.com/rancher/k3k v0.3.3
helm.sh/helm/v3 v3.15.3
k8s.io/api v0.31.4
Expand Down
91 changes: 91 additions & 0 deletions internal/controller/controlplane/controller_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package controlplane_test

import (
"context"
"os"
"path"
"path/filepath"
"testing"
"time"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"

clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

"github.com/rancher/cluster-api-provider-k3k/api/controlplane/v1alpha1"

. "github.com/onsi/gomega"
)

func TestController(t *testing.T) {
RegisterTestingT(t)

binaryAssetsDirectory := os.Getenv("KUBEBUILDER_ASSETS")
if binaryAssetsDirectory == "" {
binaryAssetsDirectory = "/usr/local/kubebuilder/bin"
}

tmpKubebuilderDir := path.Join(os.TempDir(), "kubebuilder")
err := os.MkdirAll(tmpKubebuilderDir, 0o755)
Expect(err).ToNot(HaveOccurred())

tempDir, err := os.MkdirTemp(tmpKubebuilderDir, "envtest-*")
Expect(err).ToNot(HaveOccurred())

err = os.CopyFS(tempDir, os.DirFS(binaryAssetsDirectory))
Expect(err).ToNot(HaveOccurred())

testEnv := &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "api", "controlplane", "v1alpha1")},
ErrorIfCRDPathMissing: true,
BinaryAssetsDirectory: tempDir,
Scheme: buildScheme(),
}

cfg, err := testEnv.Start()
Expect(err).ToNot(HaveOccurred())

_, err = kubernetes.NewForConfig(cfg)
Expect(err).ToNot(HaveOccurred())

_, err = client.New(cfg, client.Options{Scheme: testEnv.Scheme})
Expect(err).ToNot(HaveOccurred())

manager, err := ctrl.NewManager(cfg, ctrl.Options{
// disable the metrics server
Metrics: metricsserver.Options{BindAddress: "0"},
Scheme: testEnv.Scheme,
})
Expect(err).ToNot(HaveOccurred())

go func() {
t.Log("starting manager")
startErr := manager.Start(context.Background())
Expect(startErr).ToNot(HaveOccurred())
}()

t.Log("waiting for 10s")
time.Sleep(10 * time.Second)

t.Log("stopping testEnv")
t.Log("manager err", testEnv.Stop())

err = os.RemoveAll(tmpKubebuilderDir)
Expect(err).ToNot(HaveOccurred())
}

func buildScheme() *runtime.Scheme {
scheme := runtime.NewScheme()

err := clientgoscheme.AddToScheme(scheme)
Expect(err).ToNot(HaveOccurred())
err = v1alpha1.AddToScheme(scheme)
Expect(err).ToNot(HaveOccurred())

return scheme
}
15 changes: 8 additions & 7 deletions internal/controller/controlplane/k3kcontrolplane_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,25 @@ import (
"time"

"github.com/go-logr/logr"
upstream "github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
"github.com/rancher/k3k/pkg/controller/kubeconfig"
"helm.sh/helm/v3/pkg/storage/driver"
v1 "k8s.io/api/core/v1"
apiError "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

upstream "github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
v1 "k8s.io/api/core/v1"
apiError "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
clusterv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
capiutil "sigs.k8s.io/cluster-api/util"
capiKubeconfig "sigs.k8s.io/cluster-api/util/kubeconfig"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

controlplanev1 "github.com/rancher/cluster-api-provider-k3k/api/controlplane/v1alpha1"
infrastructurev1 "github.com/rancher/cluster-api-provider-k3k/api/infrastructure/v1alpha1"
Expand Down
Loading