From c86a45c7b0e433468b73ecfcd5fbfc72fd2c21e8 Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Fri, 22 May 2026 17:58:12 -0400 Subject: [PATCH 1/3] chore: Remove VPC/VPCAttachment CRDs, operator, and related code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VPC and VPCAttachment CRD management is moving to a separate operator project. Galactic now focuses solely on the SRv6 data plane: the DaemonSet agent and CNI plugin receive pre-populated identifiers via CNI config and act on them directly. Removed: - pkg/apis/v1alpha/ — VPC and VPCAttachment CRD types - internal/operator/ — all controllers, webhook, cniconfig, identifier - internal/cmd/operator/ — operator subcommand - config/crd/bases/ — VPC and VPCAttachment CRD YAMLs - config/rbac/ — VPC/VPCAttachment role files - config/samples/ — VPC, VPCAttachment, and pod samples - config/webhook/ — pod mutation webhook manifests - config/certmanager/certificate-webhook.yaml - config/default/manager_webhook_patch.yaml - config/network-policy/allow-webhook-traffic.yaml Updated: - cmd/galactic/main.go — operator subcommand removed; agent/cni/version remain - Makefile — removed manifests, generate, run-operator, setup-envtest targets - go.mod/go.sum — dropped controller-runtime and ~60 transitive dependencies - config/ kustomization files — removed dangling references - CLAUDE.md, AGENTS.md, README.md, CONVENTIONS.md — reflect new scope Co-Authored-By: Claude Sonnet 4.6 --- AGENTS.md | 45 ++-- CONVENTIONS.md | 107 ++------ Makefile | 53 +--- README.md | 24 +- cmd/galactic/main.go | 3 - config/certmanager/certificate-webhook.yaml | 20 -- config/certmanager/kustomization.yaml | 1 - ...galactic.datumapis.com_vpcattachments.yaml | 142 ---------- .../bases/galactic.datumapis.com_vpcs.yaml | 71 ----- config/crd/kustomization.yaml | 2 - config/default/kustomization.yaml | 127 --------- config/default/manager_webhook_patch.yaml | 31 --- .../network-policy/allow-webhook-traffic.yaml | 27 -- config/network-policy/kustomization.yaml | 1 - config/rbac/kustomization.yaml | 11 - config/rbac/role.yaml | 29 -- config/rbac/vpc_admin_role.yaml | 27 -- config/rbac/vpc_editor_role.yaml | 33 --- config/rbac/vpc_viewer_role.yaml | 29 -- config/rbac/vpcattachment_admin_role.yaml | 27 -- config/rbac/vpcattachment_editor_role.yaml | 33 --- config/rbac/vpcattachment_viewer_role.yaml | 29 -- config/samples/galactic_v1alpha_vpc.yaml | 11 - .../galactic_v1alpha_vpcattachment.yaml | 27 -- config/samples/kustomization.yaml | 2 - config/samples/pod.yaml | 11 - config/webhook/kustomization.yaml | 37 --- config/webhook/kustomizeconfig.yaml | 22 -- config/webhook/manifests.yaml | 52 ---- config/webhook/service.yaml | 16 -- go.mod | 59 +---- go.sum | 160 ----------- internal/cmd/operator/operator.go | 169 ------------ internal/operator/cniconfig/cniconfig.go | 103 -------- internal/operator/cniconfig/cniconfig_test.go | 105 -------- internal/operator/controller/suite_test.go | 104 -------- .../operator/controller/vpc_controller.go | 81 ------ .../controller/vpc_controller_test.go | 100 ------- .../controller/vpcattachment_controller.go | 130 --------- .../vpcattachment_controller_test.go | 151 ----------- internal/operator/identifier/identifier.go | 54 ---- .../operator/identifier/identifier_test.go | 69 ----- internal/operator/webhook/v1/pod_webhook.go | 123 --------- .../operator/webhook/v1/pod_webhook_test.go | 136 ---------- .../operator/webhook/v1/webhook_suite_test.go | 151 ----------- pkg/apis/v1alpha/groupversion_info.go | 24 -- pkg/apis/v1alpha/vpc_types.go | 62 ----- pkg/apis/v1alpha/vpcattachment_types.go | 96 ------- pkg/apis/v1alpha/zz_generated.deepcopy.go | 250 ------------------ 49 files changed, 51 insertions(+), 3126 deletions(-) delete mode 100644 config/certmanager/certificate-webhook.yaml delete mode 100644 config/crd/bases/galactic.datumapis.com_vpcattachments.yaml delete mode 100644 config/crd/bases/galactic.datumapis.com_vpcs.yaml delete mode 100644 config/default/manager_webhook_patch.yaml delete mode 100644 config/network-policy/allow-webhook-traffic.yaml delete mode 100644 config/rbac/vpc_admin_role.yaml delete mode 100644 config/rbac/vpc_editor_role.yaml delete mode 100644 config/rbac/vpc_viewer_role.yaml delete mode 100644 config/rbac/vpcattachment_admin_role.yaml delete mode 100644 config/rbac/vpcattachment_editor_role.yaml delete mode 100644 config/rbac/vpcattachment_viewer_role.yaml delete mode 100644 config/samples/galactic_v1alpha_vpc.yaml delete mode 100644 config/samples/galactic_v1alpha_vpcattachment.yaml delete mode 100644 config/samples/pod.yaml delete mode 100644 config/webhook/kustomization.yaml delete mode 100644 config/webhook/kustomizeconfig.yaml delete mode 100644 config/webhook/manifests.yaml delete mode 100644 config/webhook/service.yaml delete mode 100644 internal/cmd/operator/operator.go delete mode 100644 internal/operator/cniconfig/cniconfig.go delete mode 100644 internal/operator/cniconfig/cniconfig_test.go delete mode 100644 internal/operator/controller/suite_test.go delete mode 100644 internal/operator/controller/vpc_controller.go delete mode 100644 internal/operator/controller/vpc_controller_test.go delete mode 100644 internal/operator/controller/vpcattachment_controller.go delete mode 100644 internal/operator/controller/vpcattachment_controller_test.go delete mode 100644 internal/operator/identifier/identifier.go delete mode 100644 internal/operator/identifier/identifier_test.go delete mode 100644 internal/operator/webhook/v1/pod_webhook.go delete mode 100644 internal/operator/webhook/v1/pod_webhook_test.go delete mode 100644 internal/operator/webhook/v1/webhook_suite_test.go delete mode 100644 pkg/apis/v1alpha/groupversion_info.go delete mode 100644 pkg/apis/v1alpha/vpc_types.go delete mode 100644 pkg/apis/v1alpha/vpcattachment_types.go delete mode 100644 pkg/apis/v1alpha/zz_generated.deepcopy.go diff --git a/AGENTS.md b/AGENTS.md index a0c01c9..7547ebf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,65 +2,54 @@ ## Purpose & Architecture -Galactic is a Kubernetes network operator that gives pods declarative multi-cloud VPC connectivity using SRv6 and kernel VRF isolation. Users create two CRDs (`VPC`, `VPCAttachment`) and annotate pods; Galactic handles all routing. The control plane is a Go operator (`internal/operator/controller/`) that assigns identifiers and generates Multus `NetworkAttachmentDefinition` resources. A DaemonSet agent (`internal/agent/srv6/`) manages kernel SRv6 routes and VRFs per node. The CNI plugin (`internal/cni/`) runs in-process with the agent, registering container endpoints via gRPC. BGP is used as the control plane for distributing SRv6 routes between agents. +Galactic is the SRv6 data plane for multi-cloud VPC networking. It consists of a DaemonSet agent (`internal/agent/srv6/`) that manages kernel SRv6 routes and VRFs per node, and a CNI plugin (`internal/cni/`) that registers container endpoints with the agent via gRPC. VPC and VPCAttachment CRD management lives in a separate operator project; Galactic receives pre-populated identifiers through the CNI config and acts on them. BGP is used as the control plane for distributing SRv6 routes between agents. -**Data flow:** VPC/VPCAttachment CRDs → operator assigns 48-bit/16-bit hex IDs → NetworkAttachmentDefinition written → pod annotation triggers webhook (adds Multus annotation) → CNI runs → gRPC registers endpoint with agent → agent manages SRv6 ingress routes locally → BGP distributes SRv6 routes between agents. +**Data flow:** CNI invoked with pre-populated VPC/VPCAttachment identifiers → gRPC registers endpoint with agent → agent manages SRv6 ingress routes locally → BGP distributes SRv6 routes between agents. **Non-obvious decisions:** -- VPC identifiers are 48-bit hex; VPCAttachment identifiers are 16-bit hex. These are embedded into IPv6 SRv6 endpoint addresses for deterministic route lookups. +- VPC identifiers are 48-bit hex; VPCAttachment identifiers are 16-bit hex. These are embedded into IPv6 SRv6 endpoint addresses for deterministic route lookups. Both are supplied by an external operator via the CNI config. - Identifiers are also Base62-encoded for interface naming (VRF: `vrfX-Y`, veth host side: `galX-Y`) to keep kernel interface name length within limits. -- The binary auto-detects CNI mode via the `CNI_COMMAND` env var; otherwise runs as a Cobra CLI with `operator`, `agent`, `cni`, `version` subcommands. +- The binary auto-detects CNI mode via the `CNI_COMMAND` env var; otherwise runs as a Cobra CLI with `agent`, `cni`, and `version` subcommands. ## Tech Stack -- **Go 1.24** (toolchain 1.24.2) — operator, agent, CNI plugin -- **controller-runtime v0.21 / k8s v1.33** — operator framework -- **Multus CNI** — multi-network for pods; Galactic generates NADs automatically +- **Go 1.24** (toolchain 1.24.2) — agent and CNI plugin +- **Multus CNI** — multi-network for pods; NAD generation is handled by the external operator - **gRPC + protobuf** — CNI-to-agent local communication (`pkg/proto/local/`) - **SRv6 + netlink** — kernel-level routing; `github.com/vishvananda/netlink` -- **BGP** — control plane for SRv6 route distribution between agents -- **Ginkgo/Gomega** — Go BDD-style tests -- **controller-gen v0.18 / kustomize v5.6** — code + manifest generation (managed by Makefile, vendored to `bin/`) +- **BGP** — control plane for SRv6 route distribution between agents (in progress) ## Development Workflow ``` make build # produces bin/galactic -make test # gen + fmt + vet + unit tests with coverage +make test # fmt + vet + unit tests with coverage make lint # golangci-lint; lint-fix applies safe auto-fixes -make run-operator # run operator against current kubeconfig make run-agent # run agent (requires root / CAP_NET_ADMIN) -make test-e2e # requires Kind; setup-test-e2e creates the cluster -make manifests # regenerate CRDs + RBAC from Go types (run after API changes) -make generate # regenerate DeepCopy methods (run after API type changes) ``` **Before every PR:** `make lint test`. -**Envtest binaries** are downloaded to `bin/` by `make setup-envtest`. CI pins Kubernetes 1.31 for controller tests. - ## Code Standards -See [CONVENTIONS.md](CONVENTIONS.md) for the full, prescriptive coding standards covering Go naming, error handling, testing patterns, API type conventions, code generation, linting, and commit messages. +See [CONVENTIONS.md](CONVENTIONS.md) for the full, prescriptive coding standards covering Go naming, error handling, testing patterns, linting, and commit messages. Summary: -- Go: `gofmt`/`goimports` enforced; golangci-lint with `errcheck`, `staticcheck`, `govet`, `revive`, `gocyclo`, `dupl`, `unused` (see `.golangci.yml`). `lll` excluded from `api/` and `internal/`. -- Generated files (`zz_generated.deepcopy.go`, CRD YAMLs) are committed; regenerate with `make generate manifests` after type changes. Never hand-edit them. -- Kubebuilder marker annotations (`+kubebuilder:rbac`, `+kubebuilder:object:root`, etc.) drive code + manifest generation — keep them accurate. +- Go: `gofmt`/`goimports` enforced; golangci-lint with `errcheck`, `staticcheck`, `govet`, `revive`, `gocyclo`, `dupl`, `unused` (see `.golangci.yml`). `lll` excluded from `internal/`. +- Generated protobuf files (`*.pb.go`, `*_grpc.pb.go`) are committed; never hand-edit them. ## Current State -- **Known debt:** e2e tests only run on `main`/release branches (not PRs), so regressions in cluster behavior can merge undetected. Unit coverage exists for `identifier`, `cniconfig`, and `pkg/common/util`; controller reconciler logic has envtest coverage but agent/CNI paths do not. +- **Known debt:** Agent and CNI kernel-path code (`internal/agent/srv6/`, `internal/cni/`) has no unit coverage; these paths are best covered by integration or e2e tests. Only `pkg/common/util` has unit test coverage. - **In flux:** The SRv6 route management (`internal/agent/srv6/`) and VRF utilities (`pkg/common/vrf/`) are the least tested and most likely to change as multi-cloud routing matures. BGP integration is in progress. ## New Developer Entry Points -1. Run `make build` to verify toolchain; run `make test` to confirm envtest and unit tests pass. -2. Read `pkg/apis/v1alpha/vpc_types.go` and `vpcattachment_types.go` — the CRD types are the core abstraction. -3. Trace `internal/operator/controller/vpcattachment_controller.go` — it wires operator reconciliation to Multus NAD generation. -4. Read `internal/cni/cni.go` (cmdAdd/cmdDel) to understand the container attach path. -5. `config/samples/` has working VPC, VPCAttachment, and annotated Pod examples. +1. Run `make build` to verify toolchain; run `make test` to confirm unit tests pass. +2. Read `internal/cni/cni.go` (cmdAdd/cmdDel) to understand the container attach path. +3. Read `internal/agent/srv6/srv6.go` to understand the agent entry point and how it manages SRv6 routes and VRFs. +4. Read `pkg/proto/local/local.go` to understand the gRPC interface between the CNI and the agent. +5. Explore `pkg/common/` for shared utilities (VRF management, sysctl helpers, CNI types). **Likely trip-ups:** - `make run-agent` requires elevated privileges (netlink, VRF, SRv6 operations need `CAP_NET_ADMIN`). -- After modifying API types, you must run both `make generate` and `make manifests` or CRD YAML and DeepCopy will be out of sync. diff --git a/CONVENTIONS.md b/CONVENTIONS.md index 7a8fec5..e630649 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -10,13 +10,11 @@ This document defines the coding standards, naming rules, error handling pattern - Module: `go.datum.net/galactic` - `cmd/galactic/main.go` — binary entry point; all Cobra subcommands registered here -- `pkg/apis/v1alpha/` — public CRD types; only add types here that are part of the Kubernetes API surface -- `pkg/common/` — utilities shared between operator, agent, and CNI +- `pkg/common/` — utilities shared between agent and CNI - `pkg/proto/local/` — gRPC / protobuf generated files plus hand-written convenience wrapper for CNI-to-agent communication -- `internal/operator/` — operator reconcilers, identifier logic, CNI config generation, webhooks - `internal/agent/srv6/` — kernel SRv6 route and VRF management - `internal/cni/` — CNI plugin (cmdAdd / cmdDel implementation) -- `internal/cmd/` — one sub-package per Cobra subcommand (`agent`, `cni`, `operator`, `version`) +- `internal/cmd/` — one sub-package per Cobra subcommand (`agent`, `cni`, `version`) Place new code in `internal/` unless it must be imported by an external caller. Prefer creating a focused sub-package over adding to an existing large one. @@ -28,19 +26,16 @@ Use three groups, separated by blank lines: 2. Third-party and Kubernetes packages 3. Internal packages (`go.datum.net/galactic/...`) -`goimports` enforces this automatically. Alias imports use the last meaningful path segment as the short name (`ctrl`, `metav1`, `corev1`, `nadv1`, `galacticv1alpha`). +`goimports` enforces this automatically. Alias imports use the last meaningful path segment as the short name (`nadv1`, `localgrpc`). ```go import ( "context" "fmt" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" + "google.golang.org/grpc" - "go.datum.net/galactic/internal/operator/identifier" + "go.datum.net/galactic/pkg/proto/local" ) ``` @@ -48,13 +43,13 @@ import ( | Element | Convention | Example | |---------|-----------|---------| -| Package | lowercase, single word, matches directory | `package controller` | -| Exported type | `CapWords` | `VPCAttachmentReconciler` | +| Package | lowercase, single word, matches directory | `package srv6` | +| Exported type | `CapWords` | `RouteIngress` | | Exported function / method | `CamelCase` | `RouteIngressAdd` | -| Unexported function / method | `camelCase` | `vpcAttachmentsToIdentifiers` | -| Exported constant | `CamelCase`, descriptive | `MaxVPC`, `MaxIdentifierAttemptsVPCAttachment` | -| Test package | `_test` | `package identifier_test` | -| K8s API import aliases | domain-prefixed group-version | `galacticv1alpha`, `nadv1`, `metav1` | +| Unexported function / method | `camelCase` | `buildSRv6Encap` | +| Exported constant | `CamelCase`, descriptive | `MaxVPC`, `MaxVPCAttachment` | +| Test package | `_test` | `package util_test` | +| K8s API import aliases | domain-prefixed group-version | `nadv1`, `metav1` | Do not use `_` in Go identifiers except in test package names. @@ -62,17 +57,10 @@ Do not use `_` in Go identifiers except in test package names. - Wrap errors with context using `fmt.Errorf("what failed: %w", err)`. The context string must complete the sentence "could not ``". - Collect multiple independent errors with `errors.Join(errs...)` and return the joined error. -- In controllers, return `ctrl.Result{}, client.IgnoreNotFound(err)` on the initial resource fetch (expected not-found on deletion). -- Return `ctrl.Result{RequeueAfter: duration}, nil` when waiting for a dependency (e.g., VPC not yet ready). Do not return an error for expected transient states. - Never swallow errors silently. If an error truly cannot be actionable, log it before discarding. - Do not add error handling for scenarios that the code guarantees cannot happen. ```go -// correct -if err := r.Get(ctx, req.NamespacedName, &vpc); err != nil { - return ctrl.Result{}, client.IgnoreNotFound(err) -} - // correct — multiple independent operations var errs []error if err := neighborproxy.Add(...); err != nil { @@ -93,52 +81,16 @@ const MaxVPC uint64 = 0xFFFFFFFFFFFF const MaxVPCAttachment uint64 = 0xFFFF ``` -### Reconciler structure - -- Reconciler struct embeds `client.Client` and `Scheme *runtime.Scheme`; add service dependencies as named pointer fields. -- All state assignments must be idempotent — guard with conditions before mutating: - ```go - if vpcAttachment.Status.Identifier == "" { - // assign once - } - ``` -- Use `controllerutil.CreateOrUpdate` for Kubernetes resources the reconciler manages. -- Always call `controllerutil.SetControllerReference` to wire ownership for garbage collection. -- Named the controller in `SetupWithManager` using `.Named("lowercase-kind")`. - -### Kubebuilder markers (API types) - -Every field in an API type must have either `// +required` or `// +optional`. Required fields must not carry `omitempty`. Optional fields must carry `omitempty`. Embedded structs (`TypeMeta`, `ObjectMeta`) carry both `omitempty` and `omitzero`. - -```go -// +required -Spec VPCSpec `json:"spec"` - -// +optional -Status VPCStatus `json:"status,omitempty,omitzero"` -``` - -RBAC markers live on the `Reconcile` method of each controller, not on the struct. - ### Code generation -Generated files (`zz_generated.deepcopy.go`, CRD YAML in `config/crd/bases/`, protobuf `*.pb.go`) must never be hand-edited. After any change to API types: - -``` -make generate # regenerates DeepCopy methods -make manifests # regenerates CRD YAML and RBAC -``` - -Both commands must be run together. Generated files are committed to version control. - -The boilerplate license header (`hack/boilerplate.go.txt`) is injected automatically by controller-gen. +Generated protobuf files (`*.pb.go`, `*_grpc.pb.go` in `pkg/proto/local/`) must never be hand-edited. Regenerate them using the `protoc` toolchain when `.proto` files change. Generated files are committed to version control. ### Linting -Run `make lint` before every PR. All linters listed in `.golangci.yml` must pass. Suppressions require a comment explaining why. Notable active linters: `errcheck`, `staticcheck`, `govet`, `revive`, `gocyclo`, `dupl`, `unused`, `ginkgolinter`. +Run `make lint` before every PR. All linters listed in `.golangci.yml` must pass. Suppressions require a comment explaining why. Notable active linters: `errcheck`, `staticcheck`, `govet`, `revive`, `gocyclo`, `dupl`, `unused`. Exclusions by path: -- `lll` is excluded from `api/*` and `internal/*` +- `lll` is excluded from `internal/*` - `dupl` is excluded from `internal/*` - The `lab/` directory is entirely excluded @@ -162,7 +114,7 @@ tests := []struct { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := id.FromValue(tt.value, identifier.MaxVPC) + got, err := id.FromValue(tt.value, MaxVPC) if (err != nil) != tt.wantError { t.Errorf("FromValue() error = %v, wantError = %v", err, tt.wantError) } @@ -177,24 +129,9 @@ for _, tt := range tests { - Name test cases using `UpperCamelCase` (e.g., `"ValidMin"`, `"InvalidSpecialMax"`). - Use `wantError bool` to test error presence; do not test error message strings unless the message is part of the contract. -### Go — controller / integration tests (Ginkgo + Gomega) - -- Dot-import both `ginkgo/v2` and `gomega` in controller test files. -- Each controller has its own `_test.go` file and shares a `suite_test.go` in the same package. -- Suite bootstrap in `suite_test.go`: one `TestXxx(t *testing.T)` function that calls `RegisterFailHandler(Fail)` then `RunSpecs(t, "Suite Name")`. -- envtest provides a real Kubernetes API server. CRDs are loaded from `config/crd/bases`. Run `make setup-envtest` before running tests. -- Annotate test steps with `By("description")` to produce readable output on failure. -- Lifecycle: `BeforeEach` for setup, `AfterEach` for cleanup; always clean up created objects. -- Assert status fields are falsy/empty immediately after creation before reconciliation: - ```go - Expect(resource.Status.Ready).To(BeFalse()) - Expect(resource.Status.Identifier).To(BeEmpty()) - ``` - ### What not to test -- Do not mock the Kubernetes API server in controller tests — use envtest. -- Do not write tests for generated code (`zz_generated.deepcopy.go`, `*.pb.go`). +- Do not write tests for generated code (`*.pb.go`, `*_grpc.pb.go`). - Agent and CNI kernel-path code (`internal/agent/srv6/`, `internal/cni/`) currently has no unit coverage; new code in those paths should prefer integration/e2e over fragile mock-heavy unit tests. --- @@ -207,12 +144,10 @@ for _, tt := range tests { --- -## Kubernetes manifests (Kustomize) +## Kubernetes manifests -- `config/` uses Kustomize. `config/default/` is the base overlay for production deployment. -- CRD manifests in `config/crd/bases/` are generated — never edit by hand. -- RBAC roles are generated from kubebuilder markers — never edit `config/rbac/role.yaml` by hand. -- `config/samples/` contains working examples of VPC, VPCAttachment, and annotated Pod; keep samples up to date with API changes. +- `config/` contains deployment manifests for the agent DaemonSet and CNI plugin. `config/default/` is the base overlay for production deployment. +- Edit manifest files directly; there is no code-generation step for manifests in this repo. --- @@ -221,7 +156,7 @@ for _, tt := range tests { Use imperative mood, sentence case, present tense. First line ≤ 72 characters. Reference issues where applicable. ``` -Add SRv6 egress route cleanup on VPCAttachment deletion +Add SRv6 egress route cleanup on endpoint removal Fixes #42 ``` @@ -236,4 +171,4 @@ Before opening a pull request, run all of the following and ensure they pass: make lint test ``` -e2e tests (`make test-e2e`) run only on `main` and release branches, not on PRs. Do not rely on them to catch regressions — write unit or integration tests instead. +Agent and CNI kernel-path code is not covered by unit tests. New code in those paths should prefer integration or e2e tests over mock-heavy unit tests. diff --git a/Makefile b/Makefile index b56106d..4e00ea9 100644 --- a/Makefile +++ b/Makefile @@ -41,14 +41,6 @@ help: ## Display this help. ##@ Development -.PHONY: manifests -manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases - -.PHONY: generate -generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." - .PHONY: fmt fmt: ## Run go fmt against code. go fmt ./... @@ -58,8 +50,8 @@ vet: ## Run go vet against code. GOOS=linux go vet ./... .PHONY: test -test: manifests generate fmt vet setup-envtest ## Run tests. - GOOS=linux KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out +test: fmt vet ## Run tests. + GOOS=linux go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out # TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'. # The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally. @@ -82,7 +74,7 @@ setup-test-e2e: ## Set up a Kind cluster for e2e tests if it does not exist esac .PHONY: test-e2e -test-e2e: setup-test-e2e manifests generate fmt vet ## Run the e2e tests. Expected an isolated environment using Kind. +test-e2e: setup-test-e2e fmt vet ## Run the e2e tests. Expected an isolated environment using Kind. KIND_CLUSTER=$(KIND_CLUSTER) go test ./test/e2e/ -v -ginkgo.v $(MAKE) cleanup-test-e2e @@ -109,13 +101,9 @@ notice: go-licenses ## Generate NOTICE file with third-party dependency license ##@ Build .PHONY: build -build: manifests generate fmt vet ## Build galactic binary. +build: fmt vet ## Build galactic binary. go build -o bin/galactic cmd/galactic/main.go -.PHONY: run-operator -run-operator: manifests generate fmt vet ## Run operator from your host. - go run ./cmd/galactic/main.go operator - .PHONY: run-agent run-agent: fmt vet ## Run agent from your host. go run ./cmd/galactic/main.go agent @@ -149,7 +137,7 @@ docker-buildx: ## Build and push docker image for the unified binary for cross-p rm build/Dockerfile.cross .PHONY: build-installer -build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. +build-installer: kustomize ## Generate a consolidated YAML with CRDs and deployment. mkdir -p dist cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} $(KUSTOMIZE) build config/default > dist/install.yaml @@ -161,15 +149,15 @@ ifndef ignore-not-found endif .PHONY: install -install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. +install: kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f - .PHONY: uninstall -uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. +uninstall: kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. $(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - .PHONY: deploy -deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. +deploy: kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f - @@ -196,18 +184,11 @@ $(LOCALBIN): KUBECTL ?= kubectl KIND ?= kind KUSTOMIZE ?= $(LOCALBIN)/kustomize -CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen -ENVTEST ?= $(LOCALBIN)/setup-envtest GOLANGCI_LINT = $(LOCALBIN)/golangci-lint GO_LICENSES ?= $(LOCALBIN)/go-licenses ## Tool Versions KUSTOMIZE_VERSION ?= v5.6.0 -CONTROLLER_TOOLS_VERSION ?= v0.18.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.6 GO_LICENSES_VERSION ?= v1.6.0 @@ -216,24 +197,6 @@ kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. $(KUSTOMIZE): $(LOCALBIN) $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_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: 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)..." - @$(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path || { \ - echo "Error: Failed to set up envtest binaries for version $(ENVTEST_K8S_VERSION)."; \ - exit 1; \ - } - -.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)) - .PHONY: golangci-lint golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. $(GOLANGCI_LINT): $(LOCALBIN) diff --git a/README.md b/README.md index 4ebbe7d..5322ba6 100644 --- a/README.md +++ b/README.md @@ -10,29 +10,9 @@ Modern organizations run workloads everywhere: AWS, Azure, GCP, on-premises, and ## Our Approach -Galactic extends Kubernetes with two simple resources—VPCs and VPCAttachments—that let you define multi-cloud network topology declaratively: +Galactic provides the SRv6 data plane that makes multi-cloud VPC connectivity work at the kernel level. It runs as a DaemonSet agent on every node, managing SRv6 routes and VRF isolation, and as a CNI plugin that attaches pods to the correct virtual network. VPC and VPCAttachment definitions are managed by a companion operator; Galactic acts on the identifiers that operator assigns. -```yaml -apiVersion: networking.datum.net/v1alpha1 -kind: VPC -metadata: - name: production -spec: - ipv4CIDRBlocks: - - 10.100.0.0/16 -``` - -Any pod can join the VPC with a single annotation: - -```yaml -metadata: - annotations: - networking.datum.net/vpc-attachment: us-west -``` - -That's it. Your pod now has an interface connected to the VPC, able to communicate with any other attached workload—regardless of which cloud or region it's running in. - -Under the hood, Galactic uses Segment Routing over IPv6 (SRv6) for efficient, deterministic routing and Virtual Routing and Forwarding (VRF) for true network isolation at the kernel level. +Under the hood, Galactic uses Segment Routing over IPv6 (SRv6) for efficient, deterministic routing and Virtual Routing and Forwarding (VRF) for true network isolation at the kernel level. BGP is used to distribute SRv6 routes between agents across nodes and clusters. ## Why Galactic diff --git a/cmd/galactic/main.go b/cmd/galactic/main.go index d432d20..aaa88df 100644 --- a/cmd/galactic/main.go +++ b/cmd/galactic/main.go @@ -12,7 +12,6 @@ import ( "go.datum.net/galactic/internal/cmd/agent" "go.datum.net/galactic/internal/cmd/cni" - "go.datum.net/galactic/internal/cmd/operator" "go.datum.net/galactic/internal/cmd/version" ) @@ -34,14 +33,12 @@ func main() { Long: `Galactic provides VPC connectivity across multiple clouds using SRv6 packet routing. This unified binary supports multiple modes of operation: -- operator: Kubernetes operator for VPC/VPCAttachment CRDs - agent: Local network agent for SRv6 route management - cni: CNI plugin for container network attachment `, } // Add subcommands - rootCmd.AddCommand(operator.NewCommand()) rootCmd.AddCommand(agent.NewCommand()) rootCmd.AddCommand(cni.NewCommand()) rootCmd.AddCommand(version.NewCommand()) diff --git a/config/certmanager/certificate-webhook.yaml b/config/certmanager/certificate-webhook.yaml deleted file mode 100644 index 4a5f93e..0000000 --- a/config/certmanager/certificate-webhook.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# The following manifests contain a self-signed issuer CR and a certificate CR. -# More document can be found at https://docs.cert-manager.io -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml - namespace: system -spec: - # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize - # replacements in the config/default/kustomization.yaml file. - dnsNames: - - SERVICE_NAME.SERVICE_NAMESPACE.svc - - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml index fcb7498..72308b8 100644 --- a/config/certmanager/kustomization.yaml +++ b/config/certmanager/kustomization.yaml @@ -1,6 +1,5 @@ resources: - issuer.yaml -- certificate-webhook.yaml - certificate-metrics.yaml configurations: diff --git a/config/crd/bases/galactic.datumapis.com_vpcattachments.yaml b/config/crd/bases/galactic.datumapis.com_vpcattachments.yaml deleted file mode 100644 index 9e82cad..0000000 --- a/config/crd/bases/galactic.datumapis.com_vpcattachments.yaml +++ /dev/null @@ -1,142 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: vpcattachments.galactic.datumapis.com -spec: - group: galactic.datumapis.com - names: - kind: VPCAttachment - listKind: VPCAttachmentList - plural: vpcattachments - singular: vpcattachment - scope: Namespaced - versions: - - name: v1alpha - schema: - openAPIV3Schema: - description: VPCAttachment is the Schema for the vpcattachments API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: spec defines the desired state of VPCAttachment - properties: - interface: - description: Interface defines the network interface configuration. - properties: - addresses: - description: A list of IPv4 or IPv6 addresses associated with - the interface. - items: - type: string - minItems: 1 - type: array - name: - default: galactic0 - description: Name of the interface (e.g., eth0). - type: string - required: - - addresses - - name - type: object - routes: - description: Routes defines additional routing entries for the VPCAttachment. - items: - description: VPCAttachmentRoute defines a routing entry for the - VPCAttachment. - properties: - destination: - description: IPv4 or IPv6 destination network in CIDR notation. - type: string - via: - description: Via is the next hop address. - type: string - required: - - destination - type: object - type: array - vpc: - description: VPC this attachment belongs to. - properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: |- - If referring to a piece of an object instead of an entire object, this string - should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container within a pod, this would take on a value like: - "spec.containers{name}" (where "name" refers to the name of the container that triggered - the event) or if no container name is specified "spec.containers[2]" (container with - index 2 in this pod). This syntax is chosen only to have some well-defined way of - referencing a part of an object. - type: string - kind: - description: |- - Kind of the referent. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - namespace: - description: |- - Namespace of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ - type: string - resourceVersion: - description: |- - Specific resourceVersion to which this reference is made, if any. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency - type: string - uid: - description: |- - UID of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids - type: string - type: object - x-kubernetes-map-type: atomic - required: - - interface - - vpc - type: object - status: - description: status defines the observed state of VPCAttachment - properties: - identifier: - description: A unique identifier assigned to this VPCAttachment - type: string - ready: - default: false - description: Indicates whether the VPCAttachment is ready for use - type: boolean - required: - - ready - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/bases/galactic.datumapis.com_vpcs.yaml b/config/crd/bases/galactic.datumapis.com_vpcs.yaml deleted file mode 100644 index d382f84..0000000 --- a/config/crd/bases/galactic.datumapis.com_vpcs.yaml +++ /dev/null @@ -1,71 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: vpcs.galactic.datumapis.com -spec: - group: galactic.datumapis.com - names: - kind: VPC - listKind: VPCList - plural: vpcs - singular: vpc - scope: Namespaced - versions: - - name: v1alpha - schema: - openAPIV3Schema: - description: VPC is the Schema for the vpcs API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: spec defines the desired state of a VPC - properties: - networks: - description: A list of networks in IPv4 or IPv6 CIDR notation associated - with the VPC - items: - type: string - minItems: 1 - type: array - required: - - networks - type: object - status: - description: status defines the observed state of a VPC - properties: - identifier: - description: A unique identifier assigned to this VPC - type: string - ready: - default: false - description: Indicates whether the VPC is ready for use - type: boolean - required: - - ready - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index ff1351e..5cbc2e7 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -2,8 +2,6 @@ # since it depends on service name and namespace that are out of this kustomize package. # It should be run by config/default resources: -- bases/galactic.datumapis.com_vpcs.yaml -- bases/galactic.datumapis.com_vpcattachments.yaml - bases/k8s.cni.cncf.io_network-attachment-definitions.yaml # +kubebuilder:scaffold:crdkustomizeresource diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 0837f82..95df19b 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -18,11 +18,6 @@ resources: - ../crd - ../rbac - ../manager -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -- ../webhook -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -- ../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus # [METRICS] Expose the controller manager metrics service. @@ -48,12 +43,6 @@ patches: # target: # kind: Deployment -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -- path: manager_webhook_patch.yaml - target: - kind: Deployment - # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. # Uncomment the following replacements to add the cert-manager CA injection annotations replacements: @@ -116,119 +105,3 @@ replacements: # delimiter: '.' # index: 1 # create: true - - - source: # Uncomment the following block if you have any webhook - kind: Service - version: v1 - name: webhook-service - fieldPath: .metadata.name # Name of the service - targets: - - select: - kind: Certificate - group: cert-manager.io - version: v1 - name: serving-cert - fieldPaths: - - .spec.dnsNames.0 - - .spec.dnsNames.1 - options: - delimiter: '.' - index: 0 - create: true - - source: - kind: Service - version: v1 - name: webhook-service - fieldPath: .metadata.namespace # Namespace of the service - targets: - - select: - kind: Certificate - group: cert-manager.io - version: v1 - name: serving-cert - fieldPaths: - - .spec.dnsNames.0 - - .spec.dnsNames.1 - options: - delimiter: '.' - index: 1 - create: true - - - source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation) - kind: Certificate - group: cert-manager.io - version: v1 - name: serving-cert # This name should match the one in certificate.yaml - fieldPath: .metadata.namespace # Namespace of the certificate CR - targets: - - select: - kind: ValidatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - create: true - - source: - kind: Certificate - group: cert-manager.io - version: v1 - name: serving-cert - fieldPath: .metadata.name - targets: - - select: - kind: ValidatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 1 - create: true - - - source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting ) - kind: Certificate - group: cert-manager.io - version: v1 - name: serving-cert - fieldPath: .metadata.namespace # Namespace of the certificate CR - targets: - - select: - kind: MutatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - create: true - - source: - kind: Certificate - group: cert-manager.io - version: v1 - name: serving-cert - fieldPath: .metadata.name - targets: - - select: - kind: MutatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 1 - create: true - -# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion) -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPath: .metadata.namespace # Namespace of the certificate CR -# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. -# +kubebuilder:scaffold:crdkustomizecainjectionns -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert -# fieldPath: .metadata.name -# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. -# +kubebuilder:scaffold:crdkustomizecainjectionname diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml deleted file mode 100644 index 963c8a4..0000000 --- a/config/default/manager_webhook_patch.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# This patch ensures the webhook certificates are properly mounted in the manager container. -# It configures the necessary arguments, volumes, volume mounts, and container ports. - -# Add the --webhook-cert-path argument for configuring the webhook certificate path -- op: add - path: /spec/template/spec/containers/0/args/- - value: --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs - -# Add the volumeMount for the webhook certificates -- op: add - path: /spec/template/spec/containers/0/volumeMounts/- - value: - mountPath: /tmp/k8s-webhook-server/serving-certs - name: webhook-certs - readOnly: true - -# Add the port configuration for the webhook server -- op: add - path: /spec/template/spec/containers/0/ports/- - value: - containerPort: 9443 - name: webhook-server - protocol: TCP - -# Add the volume configuration for the webhook certificates -- op: add - path: /spec/template/spec/volumes/- - value: - name: webhook-certs - secret: - secretName: webhook-server-cert diff --git a/config/network-policy/allow-webhook-traffic.yaml b/config/network-policy/allow-webhook-traffic.yaml deleted file mode 100644 index f2e2f04..0000000 --- a/config/network-policy/allow-webhook-traffic.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# This NetworkPolicy allows ingress traffic to your webhook server running -# as part of the controller-manager from specific namespaces and pods. CR(s) which uses webhooks -# will only work when applied in namespaces labeled with 'webhook: enabled' -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: allow-webhook-traffic - namespace: system -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: galactic-operator - policyTypes: - - Ingress - ingress: - # This allows ingress traffic from any namespace with the label webhook: enabled - - from: - - namespaceSelector: - matchLabels: - webhook: enabled # Only from namespaces with this label - ports: - - port: 443 - protocol: TCP diff --git a/config/network-policy/kustomization.yaml b/config/network-policy/kustomization.yaml index 0872bee..ec0fb5e 100644 --- a/config/network-policy/kustomization.yaml +++ b/config/network-policy/kustomization.yaml @@ -1,3 +1,2 @@ resources: -- allow-webhook-traffic.yaml - allow-metrics-traffic.yaml diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index 7378969..5619aa0 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -18,14 +18,3 @@ resources: - metrics_auth_role.yaml - metrics_auth_role_binding.yaml - metrics_reader_role.yaml -# For each CRD, "Admin", "Editor" and "Viewer" roles are scaffolded by -# default, aiding admins in cluster management. Those roles are -# not used by the galactic-operator itself. You can comment the following lines -# if you do not want those helpers be installed with your Project. -- vpcattachment_admin_role.yaml -- vpcattachment_editor_role.yaml -- vpcattachment_viewer_role.yaml -- vpc_admin_role.yaml -- vpc_editor_role.yaml -- vpc_viewer_role.yaml - diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 42e239b..a548346 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -4,35 +4,6 @@ kind: ClusterRole metadata: name: manager-role rules: -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments - - vpcs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments/finalizers - - vpcs/finalizers - verbs: - - update -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments/status - - vpcs/status - verbs: - - get - - patch - - update - apiGroups: - k8s.cni.cncf.io resources: diff --git a/config/rbac/vpc_admin_role.yaml b/config/rbac/vpc_admin_role.yaml deleted file mode 100644 index a172374..0000000 --- a/config/rbac/vpc_admin_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# This rule is not used by the project galactic-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over galactic.datumapis.com. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: vpc-admin-role -rules: -- apiGroups: - - galactic.datumapis.com - resources: - - vpcs - verbs: - - '*' -- apiGroups: - - galactic.datumapis.com - resources: - - vpcs/status - verbs: - - get diff --git a/config/rbac/vpc_editor_role.yaml b/config/rbac/vpc_editor_role.yaml deleted file mode 100644 index 9cc30fb..0000000 --- a/config/rbac/vpc_editor_role.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# This rule is not used by the project galactic-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the galactic.datumapis.com. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: vpc-editor-role -rules: -- apiGroups: - - galactic.datumapis.com - resources: - - vpcs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - galactic.datumapis.com - resources: - - vpcs/status - verbs: - - get diff --git a/config/rbac/vpc_viewer_role.yaml b/config/rbac/vpc_viewer_role.yaml deleted file mode 100644 index 93f7d0c..0000000 --- a/config/rbac/vpc_viewer_role.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# This rule is not used by the project galactic-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to galactic.datumapis.com resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: vpc-viewer-role -rules: -- apiGroups: - - galactic.datumapis.com - resources: - - vpcs - verbs: - - get - - list - - watch -- apiGroups: - - galactic.datumapis.com - resources: - - vpcs/status - verbs: - - get diff --git a/config/rbac/vpcattachment_admin_role.yaml b/config/rbac/vpcattachment_admin_role.yaml deleted file mode 100644 index d0c7499..0000000 --- a/config/rbac/vpcattachment_admin_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# This rule is not used by the project galactic-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over galactic.datumapis.com. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: vpcattachment-admin-role -rules: -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments - verbs: - - '*' -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments/status - verbs: - - get diff --git a/config/rbac/vpcattachment_editor_role.yaml b/config/rbac/vpcattachment_editor_role.yaml deleted file mode 100644 index 7c33269..0000000 --- a/config/rbac/vpcattachment_editor_role.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# This rule is not used by the project galactic-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the galactic.datumapis.com. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: vpcattachment-editor-role -rules: -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments/status - verbs: - - get diff --git a/config/rbac/vpcattachment_viewer_role.yaml b/config/rbac/vpcattachment_viewer_role.yaml deleted file mode 100644 index 8392ad9..0000000 --- a/config/rbac/vpcattachment_viewer_role.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# This rule is not used by the project galactic-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to galactic.datumapis.com resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: vpcattachment-viewer-role -rules: -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments - verbs: - - get - - list - - watch -- apiGroups: - - galactic.datumapis.com - resources: - - vpcattachments/status - verbs: - - get diff --git a/config/samples/galactic_v1alpha_vpc.yaml b/config/samples/galactic_v1alpha_vpc.yaml deleted file mode 100644 index 84ed43d..0000000 --- a/config/samples/galactic_v1alpha_vpc.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: galactic.datumapis.com/v1alpha -kind: VPC -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: vpc-sample -spec: - networks: - - 10.0.0.0/24 - - 2001:1::/64 diff --git a/config/samples/galactic_v1alpha_vpcattachment.yaml b/config/samples/galactic_v1alpha_vpcattachment.yaml deleted file mode 100644 index 1710147..0000000 --- a/config/samples/galactic_v1alpha_vpcattachment.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: galactic.datumapis.com/v1alpha -kind: VPCAttachment -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: vpcattachment-sample -spec: - vpc: - apiVersion: galactic.datumapis.com/v1alpha - kind: VPC - name: vpc-sample - namespace: default - interface: - name: galactic0 - addresses: - - 10.1.1.1/24 - - 2001:10:1:1::1/64 - routes: - - destination: 192.168.1.0/24 - via: 10.1.1.1 - - destination: 2001:1::/64 - via: 2001:10:1:1::1 - - destination: 192.168.2.0/24 - via: 10.1.1.2 - - destination: 2001:2::/64 - via: 2001:10:1:1::2 diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 008e0c3..ad50810 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -1,5 +1,3 @@ ## Append samples of your project ## resources: -- galactic_v1alpha_vpc.yaml -- galactic_v1alpha_vpcattachment.yaml # +kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/pod.yaml b/config/samples/pod.yaml deleted file mode 100644 index a579c03..0000000 --- a/config/samples/pod.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: pod-sample - annotations: - k8s.v1alpha.galactic.datumapis.com/vpc-attachment: vpcattachment-sample -spec: - containers: - - name: pod-sample - command: ["/bin/ash", "-c", "trap : TERM INT; sleep infinity & wait"] - image: alpine diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml deleted file mode 100644 index 26359b4..0000000 --- a/config/webhook/kustomization.yaml +++ /dev/null @@ -1,37 +0,0 @@ -resources: -- manifests.yaml -- service.yaml - -configurations: -- kustomizeconfig.yaml - -patches: -- patch: |- - apiVersion: admissionregistration.k8s.io/v1 - kind: MutatingWebhookConfiguration - metadata: - name: mutating-webhook-configuration - webhooks: - - name: mpod-v1.kb.io - matchConditions: - - name: vpc-attachment-annotation-exists - expression: > - object != null && - has(object.metadata) && - has(object.metadata.annotations) && - "k8s.v1alpha.galactic.datumapis.com/vpc-attachment" in object.metadata.annotations - -- patch: |- - apiVersion: admissionregistration.k8s.io/v1 - kind: ValidatingWebhookConfiguration - metadata: - name: validating-webhook-configuration - webhooks: - - name: vpod-v1.kb.io - matchConditions: - - name: vpc-attachment-annotation-exists - expression: > - object != null && - has(object.metadata) && - has(object.metadata.annotations) && - "k8s.v1alpha.galactic.datumapis.com/vpc-attachment" in object.metadata.annotations diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml deleted file mode 100644 index 206316e..0000000 --- a/config/webhook/kustomizeconfig.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# the following config is for teaching kustomize where to look at when substituting nameReference. -# It requires kustomize v2.1.0 or newer to work properly. -nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: MutatingWebhookConfiguration - group: admissionregistration.k8s.io - path: webhooks/clientConfig/service/name - - kind: ValidatingWebhookConfiguration - group: admissionregistration.k8s.io - path: webhooks/clientConfig/service/name - -namespace: -- kind: MutatingWebhookConfiguration - group: admissionregistration.k8s.io - path: webhooks/clientConfig/service/namespace - create: true -- kind: ValidatingWebhookConfiguration - group: admissionregistration.k8s.io - path: webhooks/clientConfig/service/namespace - create: true diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml deleted file mode 100644 index 7ada62f..0000000 --- a/config/webhook/manifests.yaml +++ /dev/null @@ -1,52 +0,0 @@ ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate--v1-pod - failurePolicy: Fail - name: mpod-v1.kb.io - rules: - - apiGroups: - - "" - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - pods - sideEffects: None ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate--v1-pod - failurePolicy: Fail - name: vpod-v1.kb.io - rules: - - apiGroups: - - "" - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - pods - sideEffects: None diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml deleted file mode 100644 index 5755f38..0000000 --- a/config/webhook/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: webhook-service - namespace: system -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager - app.kubernetes.io/name: galactic-operator diff --git a/go.mod b/go.mod index bbc48bc..d6a68be 100644 --- a/go.mod +++ b/go.mod @@ -7,60 +7,24 @@ toolchain go1.24.2 require ( github.com/containernetworking/cni v1.3.0 github.com/coreos/go-iptables v0.8.0 - github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7 github.com/kenshaw/baseconv v0.1.1 github.com/lorenzosaino/go-sysctl v0.3.1 - github.com/onsi/ginkgo/v2 v2.28.2 - github.com/onsi/gomega v1.39.1 github.com/spf13/cobra v1.10.2 github.com/spf13/viper v1.21.0 github.com/vishvananda/netlink v1.3.2-0.20260404173425-c822ed716ea1 golang.org/x/sys v0.40.0 google.golang.org/grpc v1.80.0 google.golang.org/protobuf v1.36.11 - k8s.io/api v0.33.0 - k8s.io/apimachinery v0.33.0 - k8s.io/client-go v0.33.0 - sigs.k8s.io/controller-runtime v0.21.0 ) require ( github.com/BurntSushi/toml v1.1.0 // indirect - github.com/Masterminds/semver/v3 v3.4.0 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.3 // indirect - github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.6.9 // indirect - github.com/google/go-cmp v0.7.0 // indirect - github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.28.2 // indirect + github.com/onsi/gomega v1.39.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.22.0 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/afero v1.15.0 // indirect @@ -68,33 +32,16 @@ require ( github.com/spf13/pflag v1.0.10 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/vishvananda/netns v0.0.5 // indirect - github.com/x448/float16 v0.8.4 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.32.0 // indirect golang.org/x/net v0.49.0 // indirect - golang.org/x/oauth2 v0.34.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/term v0.39.0 // indirect golang.org/x/text v0.33.0 // indirect - golang.org/x/time v0.9.0 // indirect golang.org/x/tools v0.41.0 // indirect golang.org/x/tools/go/expect v0.1.1-deprecated // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect honnef.co/go/tools v0.3.2 // indirect - k8s.io/apiextensions-apiserver v0.33.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 7f02353..bcd60c2 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,6 @@ github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEmnuFjskwo= @@ -13,82 +9,32 @@ github.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNG github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= -github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= -github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= -github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= -github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= -github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= -github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= -github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= -github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= -github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7 h1:z4P744DR+PIpkjwXSEc6TvN3L6LVzmUquFgmNm8wSUc= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7/go.mod h1:CM7HAH5PNuIsqjMN0fGc1ydM74Uj+0VZFhob620nklw= github.com/kenshaw/baseconv v0.1.1 h1:oAu/C7ipUT2PqT9DT0mZDGDg4URIglizZMjPv9oCu0E= github.com/kenshaw/baseconv v0.1.1/go.mod h1:yy9zGmnnR6vgOxOQb702nVdAG30JhyYZpj/5/m0siRI= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -96,41 +42,16 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lorenzosaino/go-sysctl v0.3.1 h1:3phX80tdITw2fJjZlwbXQnDWs4S30beNcMbw0cn0HtY= github.com/lorenzosaino/go-sysctl v0.3.1/go.mod h1:5grcsBRpspKknNS1qzt1eIeRDLrhpKZAtz8Fcuvs1Rc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= -github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= -github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= -github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/ginkgo/v2 v2.28.2 h1:DTrMfpqxiNUyQ3Y0zhn1n3cOO2euFgQPYIpkWwxVFps= github.com/onsi/ginkgo/v2 v2.28.2/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE= github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -149,35 +70,14 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= -github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/vishvananda/netlink v1.3.2-0.20260404173425-c822ed716ea1 h1:Ghi0XnIPOg5XHWZa/YPPA9JJBAYWSgYNcnxDpisN1Tk= github.com/vishvananda/netlink v1.3.2-0.20260404173425-c822ed716ea1/go.mod h1:lEui7SPMd9fgxzHVGRAvTxsBGCF6PRH81o2kLWLWHgw= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= @@ -190,67 +90,37 @@ go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2W go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= -golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= -golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= -gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU= @@ -262,37 +132,7 @@ google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34= honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= -k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= -k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= -k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= -k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= -k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= -k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= -k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= -sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= -sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/cmd/operator/operator.go b/internal/cmd/operator/operator.go deleted file mode 100644 index d8b77fa..0000000 --- a/internal/cmd/operator/operator.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package operator - -import ( - "crypto/tls" - "os" - - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" - - "go.datum.net/galactic/internal/operator/controller" - "go.datum.net/galactic/internal/operator/identifier" - webhookv1 "go.datum.net/galactic/internal/operator/webhook/v1" - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" -) - -var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") -) - -func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(galacticv1alpha.AddToScheme(scheme)) -} - -type operatorFlags struct { - metricsAddr string - enableLeaderElection bool - probeAddr string - secureMetrics bool - enableHTTP2 bool - tlsOpts []func(*tls.Config) -} - -func NewCommand() *cobra.Command { - flags := &operatorFlags{} - - cmd := &cobra.Command{ - Use: "operator", - Short: "Run the Galactic Kubernetes operator", - Long: `The operator manages VPC and VPCAttachment custom resources in Kubernetes. -It reconciles resource state, assigns identifiers, and configures pod network attachments -via mutation webhooks.`, - RunE: func(cmd *cobra.Command, args []string) error { - return runOperator(flags) - }, - } - - cmd.Flags().StringVar(&flags.metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ - "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") - cmd.Flags().StringVar(&flags.probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") - cmd.Flags().BoolVar(&flags.enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - cmd.Flags().BoolVar(&flags.secureMetrics, "metrics-secure", true, - "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") - cmd.Flags().BoolVar(&flags.enableHTTP2, "enable-http2", false, - "If set, HTTP/2 will be enabled for the metrics and webhook servers") - - return cmd -} - -func runOperator(flags *operatorFlags) error { - opts := zap.Options{ - Development: true, - } - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - - // if the enable-http2 flag is false (the default), http/2 should be disabled - // due to its vulnerabilities. More specifically, disabling http/2 will - // prevent from being vulnerable to the HTTP/2 Stream Cancellation and - // Rapid Reset CVEs. For more information see: - // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 - // - https://github.com/advisories/GHSA-4374-p667-p6c8 - disableHTTP2 := func(c *tls.Config) { - setupLog.Info("disabling http/2") - c.NextProtos = []string{"http/1.1"} - } - - if !flags.enableHTTP2 { - flags.tlsOpts = append(flags.tlsOpts, disableHTTP2) - } - - webhookServer := webhook.NewServer(webhook.Options{ - TLSOpts: flags.tlsOpts, - }) - - // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. - // More info: - // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/server - // - https://book.kubebuilder.io/reference/metrics.html - metricsServerOptions := metricsserver.Options{ - BindAddress: flags.metricsAddr, - SecureServing: flags.secureMetrics, - TLSOpts: flags.tlsOpts, - } - - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - Metrics: metricsServerOptions, - WebhookServer: webhookServer, - HealthProbeBindAddress: flags.probeAddr, - LeaderElection: flags.enableLeaderElection, - LeaderElectionID: "galactic.datumapis.com", - }) - if err != nil { - setupLog.Error(err, "unable to start manager") - return err - } - - // Create identifier generator for VPC and VPCAttachment - identifierGen := identifier.New() - - // Register VPC controller - if err = (&controller.VPCReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Identifier: identifierGen, - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "VPC") - return err - } - - // Register VPCAttachment controller - if err = (&controller.VPCAttachmentReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Identifier: identifierGen, - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "VPCAttachment") - return err - } - - // Register Pod mutation webhook - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhookv1.SetupPodWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Pod") - return err - } - } - - if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") - return err - } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") - return err - } - - setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") - return err - } - - return nil -} diff --git a/internal/operator/cniconfig/cniconfig.go b/internal/operator/cniconfig/cniconfig.go deleted file mode 100644 index 5700fd1..0000000 --- a/internal/operator/cniconfig/cniconfig.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package cniconfig - -import ( - "fmt" - "net" - - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" - - "go.datum.net/galactic/pkg/common/cni" - "go.datum.net/galactic/pkg/common/util" -) - -// types inlined from CNI and Galactic CNI packages to simplify cross dependencies -type NetConfList struct { - CNIVersion string `json:"cniVersion"` - Plugins interface{} `json:"plugins"` -} - -type PluginConfGalactic struct { - Type string `json:"type"` - VPC string `json:"vpc"` - VPCAttachment string `json:"vpcattachment"` - MTU int `json:"mtu,omitempty"` - Terminations []cni.Termination `json:"terminations,omitempty"` - IPAM cni.IPAM `json:"ipam,omitempty"` -} - -func CNIConfigForVPCAttachment(vpc galacticv1alpha.VPC, vpcAttachment galacticv1alpha.VPCAttachment) (NetConfList, error) { - terminations := make([]cni.Termination, 0, 10) - addresses := make([]cni.Address, 0, 10) - routes := make([]cni.Route, 0, 10) - - netAddresses := make([]net.IP, 0, 10) // to check if a route is local - - for _, address := range vpcAttachment.Spec.Interface.Addresses { - netAddress, network, err := net.ParseCIDR(address) - if err != nil { - return NetConfList{}, err - } - netAddresses = append(netAddresses, netAddress) - addresses = append(addresses, cni.Address{Address: address}) - terminations = append(terminations, cni.Termination{Network: network.String()}) - } - - for _, route := range vpcAttachment.Spec.Routes { - _, network, err := net.ParseCIDR(route.Destination) - if err != nil { - return NetConfList{}, err - } - - if route.Via != "" { - via := net.ParseIP(route.Via) - if via == nil { - return NetConfList{}, fmt.Errorf("failed to parse route via %q", route.Via) - } - - local := false - for _, netAddress := range netAddresses { - if via.Equal(netAddress) { - local = true - break - } - } - if local { // local routes are terminations - terminations = append(terminations, cni.Termination{Network: network.String(), Via: via.String()}) - } else { - routes = append(routes, cni.Route{Dst: network.String(), GW: via.String()}) - } - } - } - - vpcIdentifierBase62, err := util.HexToBase62(vpc.Status.Identifier) - if err != nil { - return NetConfList{}, err - } - vpcAttachmentIdentifierBase62, err := util.HexToBase62(vpcAttachment.Status.Identifier) - if err != nil { - return NetConfList{}, err - } - - // TODO Change to use VPC & VPCAttachment identifiers once CNI is adjusted - return NetConfList{ - CNIVersion: "0.4.0", - Plugins: []interface{}{ - PluginConfGalactic{ - Type: "galactic", - VPC: vpcIdentifierBase62, - VPCAttachment: vpcAttachmentIdentifierBase62, - MTU: 1300, - Terminations: terminations, - IPAM: cni.IPAM{ - Type: "static", - Addresses: addresses, - Routes: routes, - }, - }, - }, - }, nil -} diff --git a/internal/operator/cniconfig/cniconfig_test.go b/internal/operator/cniconfig/cniconfig_test.go deleted file mode 100644 index f03fc5a..0000000 --- a/internal/operator/cniconfig/cniconfig_test.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package cniconfig_test - -import ( - "reflect" - "testing" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" - - "go.datum.net/galactic/internal/operator/cniconfig" - "go.datum.net/galactic/pkg/common/cni" -) - -func TestCNIConfigForVPCAttachment(t *testing.T) { - expected := cniconfig.NetConfList{ - CNIVersion: "0.4.0", - Plugins: []interface{}{ - cniconfig.PluginConfGalactic{ - Type: "galactic", - VPC: "1hVwxnaA7", - VPCAttachment: "h31", - MTU: 1300, - Terminations: []cni.Termination{ - {Network: "10.1.1.0/24"}, - {Network: "2001:10:1:1::/64"}, - {Network: "192.168.1.0/24", Via: "10.1.1.1"}, - {Network: "2001:1::/64", Via: "2001:10:1:1::1"}, - }, - IPAM: cni.IPAM{ - Type: "static", - Addresses: []cni.Address{ - {Address: "10.1.1.1/24"}, - {Address: "2001:10:1:1::1/64"}, - }, - Routes: []cni.Route{ - {Dst: "192.168.2.0/24", GW: "10.1.1.2"}, - {Dst: "2001:2::/64", GW: "2001:10:1:1::2"}, - }, - }, - }, - }, - } - - vpc := galacticv1alpha.VPC{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-vpc", - Namespace: "default", - }, - Spec: galacticv1alpha.VPCSpec{ - Networks: []string{ - "10.1.1.0/24", - "2001:10:1:1::/64", - }, - }, - Status: galacticv1alpha.VPCStatus{ - Ready: true, - Identifier: "ffffffffffff", - }, - } - vpcAttachment := galacticv1alpha.VPCAttachment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-vpcattachment", - Namespace: "default", - }, - Spec: galacticv1alpha.VPCAttachmentSpec{ - VPC: corev1.ObjectReference{ - APIVersion: "galactic.datumapis.com/v1alpha", - Kind: "VPC", - Name: "test-vpc", - Namespace: "default", - }, - Interface: galacticv1alpha.VPCAttachmentInterface{ - Name: "galactic0", - Addresses: []string{ - "10.1.1.1/24", - "2001:10:1:1::1/64", - }, - }, - Routes: []galacticv1alpha.VPCAttachmentRoute{ - {Destination: "192.168.1.0/24", Via: "10.1.1.1"}, - {Destination: "2001:1::/64", Via: "2001:10:1:1::1"}, - {Destination: "192.168.2.0/24", Via: "10.1.1.2"}, - {Destination: "2001:2::/64", Via: "2001:10:1:1::2"}, - }, - }, - Status: galacticv1alpha.VPCAttachmentStatus{ - Ready: true, - Identifier: "ffff", - }, - } - actual, err := cniconfig.CNIConfigForVPCAttachment(vpc, vpcAttachment) - if err != nil { - t.Errorf("CNIConfigForVPCAttachment error: %+v", err) - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("configs not equal\nExpected: %+v\nActual: %+v", expected, actual) - } -} diff --git a/internal/operator/controller/suite_test.go b/internal/operator/controller/suite_test.go deleted file mode 100644 index 79d8177..0000000 --- a/internal/operator/controller/suite_test.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package controller - -import ( - "context" - "os" - "path/filepath" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" - // +kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - ctx context.Context - cancel context.CancelFunc - testEnv *envtest.Environment - cfg *rest.Config - k8sClient client.Client -) - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - var err error - err = galacticv1alpha.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:scheme - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - } - - // Retrieve the first found binary directory to allow running tests from IDEs - if getFirstFoundEnvTestBinaryDir() != "" { - testEnv.BinaryAssetsDirectory = getFirstFoundEnvTestBinaryDir() - } - - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) - -// getFirstFoundEnvTestBinaryDir locates the first binary in the specified path. -// ENVTEST-based tests depend on specific binaries, usually located in paths set by -// controller-runtime. When running tests directly (e.g., via an IDE) without using -// Makefile targets, the 'BinaryAssetsDirectory' must be explicitly configured. -// -// This function streamlines the process by finding the required binaries, similar to -// setting the 'KUBEBUILDER_ASSETS' environment variable. To ensure the binaries are -// properly set up, run 'make setup-envtest' beforehand. -func getFirstFoundEnvTestBinaryDir() string { - basePath := filepath.Join("..", "..", "..", "bin", "k8s") - entries, err := os.ReadDir(basePath) - if err != nil { - logf.Log.Error(err, "Failed to read directory", "path", basePath) - return "" - } - for _, entry := range entries { - if entry.IsDir() { - return filepath.Join(basePath, entry.Name()) - } - } - return "" -} diff --git a/internal/operator/controller/vpc_controller.go b/internal/operator/controller/vpc_controller.go deleted file mode 100644 index fbf62f7..0000000 --- a/internal/operator/controller/vpc_controller.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package controller - -import ( - "context" - "fmt" - "slices" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - "go.datum.net/galactic/internal/operator/identifier" - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" -) - -const MaxIdentifierAttemptsVPC = 100 - -type VPCReconciler struct { - client.Client - Scheme *runtime.Scheme - Identifier *identifier.Identifier -} - -// +kubebuilder:rbac:groups=galactic.datumapis.com,resources=vpcs,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=galactic.datumapis.com,resources=vpcs/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=galactic.datumapis.com,resources=vpcs/finalizers,verbs=update - -func (r *VPCReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - var vpc galacticv1alpha.VPC - if err := r.Get(ctx, req.NamespacedName, &vpc); err != nil { - return ctrl.Result{}, client.IgnoreNotFound(err) - } - - // We only assign an identifier once - if vpc.Status.Identifier == "" { - var existingVpcs galacticv1alpha.VPCList - if err := r.List(ctx, &existingVpcs, &client.ListOptions{}); err != nil { - return ctrl.Result{}, err - } - existingIdentifiers := vpcsToIdentifiers(existingVpcs) - - for i := 0; i <= MaxIdentifierAttemptsVPC; i++ { - if i == MaxIdentifierAttemptsVPC { - return ctrl.Result{}, fmt.Errorf("could not find an unused identifier after %d attempts", MaxIdentifierAttemptsVPC) - } - if vpc.Status.Identifier != "" && !slices.Contains(existingIdentifiers, vpc.Status.Identifier) { - break - } - vpc.Status.Identifier, _ = r.Identifier.ForVPC() - } - - vpc.Status.Ready = true - - if err := r.Status().Update(ctx, &vpc); err != nil { - return ctrl.Result{}, err - } - } - - return ctrl.Result{}, nil -} - -func (r *VPCReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&galacticv1alpha.VPC{}). - Named("vpc"). - Complete(r) -} - -func vpcsToIdentifiers(vpcs galacticv1alpha.VPCList) []string { - identifiers := make([]string, 0, len(vpcs.Items)) - for _, vpc := range vpcs.Items { - if vpc.Status.Identifier != "" { - identifiers = append(identifiers, vpc.Status.Identifier) - } - } - return identifiers -} diff --git a/internal/operator/controller/vpc_controller_test.go b/internal/operator/controller/vpc_controller_test.go deleted file mode 100644 index 40a0794..0000000 --- a/internal/operator/controller/vpc_controller_test.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package controller - -import ( - "context" - "fmt" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "go.datum.net/galactic/internal/operator/identifier" - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" -) - -var _ = Describe("VPC Controller", func() { - result_identifiers := []string{ - "f5b6726c782b", - "f68a7a2a17d9", - "ecfd7bca4d29", - } - - Context("When reconciling a resource", func() { - ctx := context.Background() - - for resourceNum := 0; resourceNum < len(result_identifiers); resourceNum++ { - var resourceName = fmt.Sprintf("vpc-%d", resourceNum) - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", - } - vpc := &galacticv1alpha.VPC{} - - BeforeEach(func() { - By("creating the custom resource for the Kind VPC") - err := k8sClient.Get(ctx, typeNamespacedName, vpc) - if err != nil && errors.IsNotFound(err) { - resource := &galacticv1alpha.VPC{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - Spec: galacticv1alpha.VPCSpec{ - Networks: []string{ - "10.1.1.0/24", - "2001:10:1:1::/64", - }, - }, - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - - err = k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - Expect(resource.Status.Ready).To(BeFalse()) - Expect(resource.Status.Identifier).To(BeEmpty()) - } - }) - - It("should successfully reconcile the resource", func() { - By("reconciling the created resource") - controllerReconciler := &VPCReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - Identifier: identifier.NewFromSeed(424242), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - resource := &galacticv1alpha.VPC{} - err = k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - Expect(resource.Status.Ready).To(BeTrue()) - Expect(resource.Status.Identifier).To(Equal(result_identifiers[resourceNum])) - }) - } - - It("should cleanup the resources", func() { - By("listing and checking the number of VPCs and then deleting them") - var vpcs galacticv1alpha.VPCList - err := k8sClient.List(ctx, &vpcs) - Expect(err).NotTo(HaveOccurred()) - Expect(vpcs.Items).To(HaveLen(len(result_identifiers))) - for _, vpc := range vpcs.Items { - Expect(k8sClient.Delete(ctx, &vpc)).To(Succeed()) - } - }) - }) -}) diff --git a/internal/operator/controller/vpcattachment_controller.go b/internal/operator/controller/vpcattachment_controller.go deleted file mode 100644 index eeb3c28..0000000 --- a/internal/operator/controller/vpcattachment_controller.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package controller - -import ( - "context" - "encoding/json" - "fmt" - "slices" - "time" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" - - "go.datum.net/galactic/internal/operator/cniconfig" - "go.datum.net/galactic/internal/operator/identifier" -) - -const MaxIdentifierAttemptsVPCAttachment = 100 - -type VPCAttachmentReconciler struct { - client.Client - Scheme *runtime.Scheme - Identifier *identifier.Identifier -} - -// +kubebuilder:rbac:groups=galactic.datumapis.com,resources=vpcattachments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=galactic.datumapis.com,resources=vpcattachments/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=galactic.datumapis.com,resources=vpcattachments/finalizers,verbs=update -// +kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch;create;update;patch;delete - -func (r *VPCAttachmentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - var vpcAttachment galacticv1alpha.VPCAttachment - if err := r.Get(ctx, req.NamespacedName, &vpcAttachment); err != nil { - return ctrl.Result{}, client.IgnoreNotFound(err) - } - vpcNamespacedName := types.NamespacedName{ - Namespace: vpcAttachment.Spec.VPC.Namespace, - Name: vpcAttachment.Spec.VPC.Name, - } - var vpc galacticv1alpha.VPC - if err := r.Get(ctx, vpcNamespacedName, &vpc); err != nil { - return ctrl.Result{}, err - } - if !vpc.Status.Ready { - return ctrl.Result{RequeueAfter: 1 * time.Second}, nil - } - - // We only assign an identifier once - if vpcAttachment.Status.Identifier == "" { - var existingVpcAttachments galacticv1alpha.VPCAttachmentList - if err := r.List(ctx, &existingVpcAttachments, &client.ListOptions{}); err != nil { - return ctrl.Result{}, err - } - existingIdentifiers := vpcAttachmentsToIdentifiers(vpc, existingVpcAttachments) - - for i := 0; i <= MaxIdentifierAttemptsVPCAttachment; i++ { - if i == MaxIdentifierAttemptsVPCAttachment { - return ctrl.Result{}, fmt.Errorf("could not find an unused identifier after %d attempts", MaxIdentifierAttemptsVPCAttachment) - } - if vpcAttachment.Status.Identifier != "" && !slices.Contains(existingIdentifiers, vpcAttachment.Status.Identifier) { - break - } - vpcAttachment.Status.Identifier, _ = r.Identifier.ForVPCAttachment() - } - - vpcAttachment.Status.Ready = true - - if err := r.Status().Update(ctx, &vpcAttachment); err != nil { - return ctrl.Result{}, err - } - } - - nad := &nadv1.NetworkAttachmentDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: vpcAttachment.Name, - Namespace: vpcAttachment.Namespace, - }, - } - _, err := controllerutil.CreateOrUpdate(ctx, r.Client, nad, func() error { - cniPluginConfig, err := cniconfig.CNIConfigForVPCAttachment(vpc, vpcAttachment) - if err != nil { - return err - } - cniPluginConfigJson, _ := json.Marshal(cniPluginConfig) - - nad.Spec = nadv1.NetworkAttachmentDefinitionSpec{ - Config: string(cniPluginConfigJson), - } - - if err := controllerutil.SetControllerReference(&vpcAttachment, nad, r.Scheme); err != nil { - return err - } - return nil - }) - if err != nil { - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -func (r *VPCAttachmentReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&galacticv1alpha.VPCAttachment{}). - Named("vpcattachment"). - Complete(r) -} - -func vpcAttachmentsToIdentifiers(vpc galacticv1alpha.VPC, vpcAttachments galacticv1alpha.VPCAttachmentList) []string { - identifiers := make([]string, 0, len(vpcAttachments.Items)) - for _, vpcAttachment := range vpcAttachments.Items { - if vpcAttachment.Status.Identifier != "" && - vpcAttachment.Spec.VPC.Name == vpc.Name && - vpcAttachment.Spec.VPC.Namespace == vpc.Namespace { - identifiers = append(identifiers, vpcAttachment.Status.Identifier) - } - } - return identifiers -} diff --git a/internal/operator/controller/vpcattachment_controller_test.go b/internal/operator/controller/vpcattachment_controller_test.go deleted file mode 100644 index 194d73f..0000000 --- a/internal/operator/controller/vpcattachment_controller_test.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package controller - -import ( - "context" - "fmt" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" - - "go.datum.net/galactic/internal/operator/identifier" -) - -var _ = Describe("VPCAttachment Controller", func() { - Context("When reconciling a resource", func() { - ctx := context.Background() - - vpcName := "test-vpc" - vpcTypeNamespacedName := types.NamespacedName{ - Name: vpcName, - Namespace: "default", - } - - BeforeEach(func() { - err := nadv1.AddToScheme(k8sClient.Scheme()) - Expect(err).NotTo(HaveOccurred()) - - By("creating the custom resource for the Kind VPC") - resource := &galacticv1alpha.VPC{} - err = k8sClient.Get(ctx, vpcTypeNamespacedName, resource) - if err != nil && errors.IsNotFound(err) { - resource := &galacticv1alpha.VPC{ - ObjectMeta: metav1.ObjectMeta{ - Name: vpcName, - Namespace: "default", - }, - Spec: galacticv1alpha.VPCSpec{ - Networks: []string{ - "10.1.1.0/24", - "2001:10:1:1::/64", - }, - }, - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - resource := &galacticv1alpha.VPC{} - err := k8sClient.Get(ctx, vpcTypeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("cleanup the specific resource instance VPC") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - - It("should successfully reconcile the resource", func() { - By("creating the custom resource for the Kind VPCAttachment") - - vpcAttachmentName := "test-vpcattachment" - vpcAttachmentTypeNamespacedName := types.NamespacedName{ - Name: vpcAttachmentName, - Namespace: "default", - } - - resource := &galacticv1alpha.VPCAttachment{ - ObjectMeta: metav1.ObjectMeta{ - Name: vpcAttachmentName, - Namespace: "default", - }, - Spec: galacticv1alpha.VPCAttachmentSpec{ - VPC: corev1.ObjectReference{ - APIVersion: "galactic.datumapis.com/v1alpha", - Kind: "VPC", - Name: vpcName, - Namespace: "default", - }, - Interface: galacticv1alpha.VPCAttachmentInterface{ - Name: "galactic0", - Addresses: []string{ - "10.1.1.1/24", - "2001:10:1:1::1/64", - }, - }, - Routes: []galacticv1alpha.VPCAttachmentRoute{ - {Destination: "192.168.1.0/24", Via: "10.1.1.1"}, - {Destination: "2001:1::/64", Via: "2001:10:1:1::1"}, - {Destination: "192.168.2.0/24", Via: "10.1.1.2"}, - {Destination: "2001:2::/64", Via: "2001:10:1:1::2"}, - }, - }, - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - Expect(resource.Status.Ready).To(BeFalse()) - Expect(resource.Status.Identifier).To(BeEmpty()) - - for run := 1; run <= 3; run++ { // make sure multiple reconcile runs work - By(fmt.Sprintf("reconciling the created resource (run #%d)", run)) - - if run > 1 { // skip the first run to test what happens if the the VPC is not ready yet - vpcControllerReconciler := &VPCReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - Identifier: identifier.NewFromSeed(424242), - } - _, err := vpcControllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: vpcTypeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - } - - vpcAttachmentControllerReconciler := &VPCAttachmentReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - Identifier: identifier.NewFromSeed(424242), - } - _, err := vpcAttachmentControllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: vpcAttachmentTypeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - - resource = &galacticv1alpha.VPCAttachment{} - err = k8sClient.Get(ctx, vpcAttachmentTypeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - if run == 1 { - Expect(resource.Status.Ready).To(BeFalse()) - } else { - Expect(resource.Status.Ready).To(BeTrue()) - Expect(resource.Status.Identifier).To(Equal("e513")) - - nadResource := &nadv1.NetworkAttachmentDefinition{} - err = k8sClient.Get(ctx, vpcAttachmentTypeNamespacedName, nadResource) - Expect(err).NotTo(HaveOccurred()) - Expect(len(nadResource.Spec.Config)).To(BeNumerically(">", 100)) - } - } - }) - }) -}) diff --git a/internal/operator/identifier/identifier.go b/internal/operator/identifier/identifier.go deleted file mode 100644 index 878d6b6..0000000 --- a/internal/operator/identifier/identifier.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package identifier - -import ( - "fmt" - "math/rand" - "time" -) - -const MaxVPC uint64 = 0xFFFFFFFFFFFF -const MaxVPCAttachment uint64 = 0xFFFF - -type Identifier struct { - r *rand.Rand -} - -func New() *Identifier { - return &Identifier{ - r: rand.New(rand.NewSource(time.Now().UnixNano())), - } -} - -func NewFromSeed(seed int64) *Identifier { - return &Identifier{ - r: rand.New(rand.NewSource(seed)), - } -} - -func (id *Identifier) FromValue(value uint64, max uint64) (string, error) { - if value == 0 || value == max { - return "", fmt.Errorf("%d is a special value that cannot be used", value) - } - if value > max { - return "", fmt.Errorf("%d exceeds maximum value %d", value, max) - } - maxLen := len(fmt.Sprintf("%x", max)) - return fmt.Sprintf("%0*x", maxLen, value), nil -} - -func (id *Identifier) FromRandom(max uint64) (string, error) { - n := uint64(id.r.Int63n(int64(max-1)) + int64(1)) - return id.FromValue(n, max) -} - -func (id *Identifier) ForVPC() (string, error) { - return id.FromRandom(MaxVPC) -} - -func (id *Identifier) ForVPCAttachment() (string, error) { - return id.FromRandom(MaxVPCAttachment) -} diff --git a/internal/operator/identifier/identifier_test.go b/internal/operator/identifier/identifier_test.go deleted file mode 100644 index 471f109..0000000 --- a/internal/operator/identifier/identifier_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package identifier_test - -import ( - "testing" - - "go.datum.net/galactic/internal/operator/identifier" -) - -func TestForVPC(t *testing.T) { - id := identifier.NewFromSeed(424242) - tests := []struct { - name string - value uint64 - wantIdentifier string - wantError bool - }{ - {"InvalidSpecialMin", 0, "", true}, - {"InvalidSpecialMax", 0xFFFFFFFFFFFF, "", true}, - {"ValidMin", 1, "000000000001", false}, - {"ValidMax", 0xFFFFFFFFFFFF - 1, "fffffffffffe", false}, - {"Valid", 12345, "000000003039", false}, - {"InvalidMax", 0xFFFFFFFFFFFF + 1, "", true}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := id.FromValue(tt.value, identifier.MaxVPC) - if (err != nil) != tt.wantError { - t.Errorf("NewFromInteger() error = %v, wantError = %v", err, tt.wantError) - } - if got != tt.wantIdentifier { - t.Errorf("NewFromInteger() got = %v, want = %v", got, tt.wantIdentifier) - } - }) - } -} - -func TestForVPCAttachment(t *testing.T) { - id := identifier.NewFromSeed(424242) - tests := []struct { - name string - value uint64 - wantIdentifier string - wantError bool - }{ - {"InvalidSpecialMin", 0, "", true}, - {"InvalidSpecialMax", 0xFFFF, "", true}, - {"ValidMin", 1, "0001", false}, - {"ValidMax", 0xFFFF - 1, "fffe", false}, - {"Valid", 12345, "3039", false}, - {"InvalidMax", 0xFFFF + 1, "", true}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := id.FromValue(tt.value, identifier.MaxVPCAttachment) - if (err != nil) != tt.wantError { - t.Errorf("NewFromInteger() error = %v, wantError = %v", err, tt.wantError) - } - if got != tt.wantIdentifier { - t.Errorf("NewFromInteger() got = %v, want = %v", got, tt.wantIdentifier) - } - }) - } -} diff --git a/internal/operator/webhook/v1/pod_webhook.go b/internal/operator/webhook/v1/pod_webhook.go deleted file mode 100644 index ea945e9..0000000 --- a/internal/operator/webhook/v1/pod_webhook.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package v1 - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" -) - -const PodAnnotationMultusNetworks = "k8s.v1.cni.cncf.io/networks" - -// nolint:unused -var podlog = logf.Log.WithName("pod-resource") - -func SetupPodWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(&corev1.Pod{}). - WithValidator(&PodCustomValidator{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }). - WithDefaulter(&PodCustomDefaulter{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }). - Complete() -} - -// +kubebuilder:webhook:path=/mutate--v1-pod,mutating=true,failurePolicy=fail,sideEffects=None,groups="",resources=pods,verbs=create;update,versions=v1,name=mpod-v1.kb.io,admissionReviewVersions=v1 - -type PodCustomDefaulter struct { - client.Client - Scheme *runtime.Scheme -} - -var _ webhook.CustomDefaulter = &PodCustomDefaulter{} - -func (d *PodCustomDefaulter) Default(ctx context.Context, obj runtime.Object) error { - pod, ok := obj.(*corev1.Pod) - - if !ok { - return fmt.Errorf("expected an Pod object but got %T", obj) - } - - if _, exists := pod.Annotations[galacticv1alpha.VPCAttachmentAnnotation]; !exists { - return nil - } - - if vpcAttachment, _ := vpcAttachmentByName(d.Client, ctx, pod.Annotations[galacticv1alpha.VPCAttachmentAnnotation], pod.GetNamespace()); vpcAttachment != nil { - pod.Annotations[PodAnnotationMultusNetworks] = fmt.Sprintf("%s@%s", vpcAttachment.Name, vpcAttachment.Spec.Interface.Name) - } - - return nil -} - -// +kubebuilder:webhook:path=/validate--v1-pod,mutating=false,failurePolicy=fail,sideEffects=None,groups="",resources=pods,verbs=create;update,versions=v1,name=vpod-v1.kb.io,admissionReviewVersions=v1 - -type PodCustomValidator struct { - client.Client - Scheme *runtime.Scheme -} - -var _ webhook.CustomValidator = &PodCustomValidator{} - -func (v *PodCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - pod, ok := obj.(*corev1.Pod) - if !ok { - return nil, fmt.Errorf("expected a Pod object but got %T", obj) - } - - if _, exists := pod.Annotations[galacticv1alpha.VPCAttachmentAnnotation]; !exists { - return nil, nil - } - - if _, err := vpcAttachmentByName(v.Client, ctx, pod.Annotations[galacticv1alpha.VPCAttachmentAnnotation], pod.GetNamespace()); err != nil { - return nil, err - } - - return nil, nil -} - -func (v *PodCustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { - _, ok := newObj.(*corev1.Pod) - if !ok { - return nil, fmt.Errorf("expected a Pod object for the newObj but got %T", newObj) - } - - return nil, nil -} - -func (v *PodCustomValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { - _, ok := obj.(*corev1.Pod) - if !ok { - return nil, fmt.Errorf("expected a Pod object but got %T", obj) - } - - return nil, nil -} - -func vpcAttachmentByName(k8sClient client.Client, ctx context.Context, name, namespace string) (*galacticv1alpha.VPCAttachment, error) { - typeNamespacedName := types.NamespacedName{ - Name: name, - Namespace: namespace, - } - var vpcAttachment galacticv1alpha.VPCAttachment - if err := k8sClient.Get(ctx, typeNamespacedName, &vpcAttachment); err != nil { - return nil, err - } - return &vpcAttachment, nil -} diff --git a/internal/operator/webhook/v1/pod_webhook_test.go b/internal/operator/webhook/v1/pod_webhook_test.go deleted file mode 100644 index 161a340..0000000 --- a/internal/operator/webhook/v1/pod_webhook_test.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package v1 - -import ( - "fmt" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" -) - -const VPCAttachmentName = "abcd1234" -const VPCAttachmentInterface = "galactic0" - -var _ = Describe("Pod Webhook", func() { - var ( - pod *corev1.Pod - validator PodCustomValidator - defaulter PodCustomDefaulter - ) - - BeforeEach(func() { - err := galacticv1alpha.AddToScheme(k8sClient.Scheme()) - Expect(err).NotTo(HaveOccurred()) - - vpcAttachment := &galacticv1alpha.VPCAttachment{ - ObjectMeta: metav1.ObjectMeta{ - Name: VPCAttachmentName, - Namespace: "default", - }, - Spec: galacticv1alpha.VPCAttachmentSpec{ - VPC: corev1.ObjectReference{ - APIVersion: "galactic.datumapis.com/v1alpha", - Kind: "VPC", - Name: "vpc-sample", - Namespace: "default", - }, - Interface: galacticv1alpha.VPCAttachmentInterface{ - Name: VPCAttachmentInterface, - Addresses: []string{ - "10.1.1.1/24", - "2001:10:1:1::1/64", - }, - }, - }, - } - Expect(k8sClient.Create(ctx, vpcAttachment)).To(Succeed()) - }) - - AfterEach(func() { - var vpcAttachments galacticv1alpha.VPCAttachmentList - err := k8sClient.List(ctx, &vpcAttachments) - Expect(err).NotTo(HaveOccurred()) - Expect(vpcAttachments.Items).To(HaveLen(1)) - for _, vpcAttachment := range vpcAttachments.Items { - Expect(k8sClient.Delete(ctx, &vpcAttachment)).To(Succeed()) - } - }) - - Context("When creating a Pod with valid VPC attachment", func() { - It("should set the networks annotation", func() { - pod = &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pod", - Namespace: "default", - Annotations: map[string]string{ - galacticv1alpha.VPCAttachmentAnnotation: VPCAttachmentName, - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "test-container", - Image: "test:latest", - }, - }, - }, - } - - validator = PodCustomValidator{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - Expect(validator.ValidateCreate(ctx, pod)).Error().NotTo(HaveOccurred()) - - defaulter = PodCustomDefaulter{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - Expect(defaulter.Default(ctx, pod)).Error().NotTo(HaveOccurred()) - Expect(pod.Annotations[PodAnnotationMultusNetworks]).To(Equal(fmt.Sprintf("%s@%s", VPCAttachmentName, VPCAttachmentInterface))) - }) - }) - - Context("When creating a Pod with invalid VPC attachment", func() { - It("should not set the networks annotation", func() { - pod = &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pod", - Namespace: "default", - Annotations: map[string]string{ - galacticv1alpha.VPCAttachmentAnnotation: "xxxxxx", - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "test-container", - Image: "test:latest", - }, - }, - }, - } - - validator = PodCustomValidator{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - Expect(validator.ValidateCreate(ctx, pod)).Error().To(HaveOccurred()) - - defaulter = PodCustomDefaulter{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - Expect(defaulter.Default(ctx, pod)).Error().NotTo(HaveOccurred()) - Expect(pod.Annotations).NotTo(HaveKey(PodAnnotationMultusNetworks)) - }) - }) -}) diff --git a/internal/operator/webhook/v1/webhook_suite_test.go b/internal/operator/webhook/v1/webhook_suite_test.go deleted file mode 100644 index 40c64f7..0000000 --- a/internal/operator/webhook/v1/webhook_suite_test.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package v1 - -import ( - "context" - "crypto/tls" - "fmt" - "net" - "os" - "path/filepath" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" - // +kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - ctx context.Context - cancel context.CancelFunc - k8sClient client.Client - cfg *rest.Config - testEnv *envtest.Environment -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - var err error - err = corev1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:scheme - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "..", "config", "webhook")}, - }, - } - - // Retrieve the first found binary directory to allow running tests from IDEs - if getFirstFoundEnvTestBinaryDir() != "" { - testEnv.BinaryAssetsDirectory = getFirstFoundEnvTestBinaryDir() - } - - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - // start webhook server using Manager. - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - WebhookServer: webhook.NewServer(webhook.Options{ - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - }), - LeaderElection: false, - Metrics: metricsserver.Options{BindAddress: "0"}, - }) - Expect(err).NotTo(HaveOccurred()) - - err = SetupPodWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready. - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - - return conn.Close() - }).Should(Succeed()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) - -// getFirstFoundEnvTestBinaryDir locates the first binary in the specified path. -// ENVTEST-based tests depend on specific binaries, usually located in paths set by -// controller-runtime. When running tests directly (e.g., via an IDE) without using -// Makefile targets, the 'BinaryAssetsDirectory' must be explicitly configured. -// -// This function streamlines the process by finding the required binaries, similar to -// setting the 'KUBEBUILDER_ASSETS' environment variable. To ensure the binaries are -// properly set up, run 'make setup-envtest' beforehand. -func getFirstFoundEnvTestBinaryDir() string { - basePath := filepath.Join("..", "..", "..", "..", "bin", "k8s") - entries, err := os.ReadDir(basePath) - if err != nil { - logf.Log.Error(err, "Failed to read directory", "path", basePath) - return "" - } - for _, entry := range entries { - if entry.IsDir() { - return filepath.Join(basePath, entry.Name()) - } - } - return "" -} diff --git a/pkg/apis/v1alpha/groupversion_info.go b/pkg/apis/v1alpha/groupversion_info.go deleted file mode 100644 index cb07cd7..0000000 --- a/pkg/apis/v1alpha/groupversion_info.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -// Package v1alpha contains API Schema definitions for the galactic v1alpha API group. -// +kubebuilder:object:generate=true -// +groupName=galactic.datumapis.com -package v1alpha - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // GroupVersion is group version used to register these objects. - GroupVersion = schema.GroupVersion{Group: "galactic.datumapis.com", Version: "v1alpha"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme. - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} - - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/pkg/apis/v1alpha/vpc_types.go b/pkg/apis/v1alpha/vpc_types.go deleted file mode 100644 index a9bb105..0000000 --- a/pkg/apis/v1alpha/vpc_types.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package v1alpha - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// VPCSpec defines the desired state of a VPC -type VPCSpec struct { - // A list of networks in IPv4 or IPv6 CIDR notation associated with the VPC - // +kubebuilder:validation:MinItems=1 - // +kubebuilder:validation:Items=string - Networks []string `json:"networks"` -} - -// VPCStatus defines the observed state of a VPC -type VPCStatus struct { - // Indicates whether the VPC is ready for use - // +required - // +default:value=false - Ready bool `json:"ready,omitempty"` - - // A unique identifier assigned to this VPC - // +optional - Identifier string `json:"identifier,omitempty"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status - -// VPC is the Schema for the vpcs API -type VPC struct { - metav1.TypeMeta `json:",inline"` - - // metadata is a standard object metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty,omitzero"` - - // spec defines the desired state of a VPC - // +required - Spec VPCSpec `json:"spec"` - - // status defines the observed state of a VPC - // +optional - Status VPCStatus `json:"status,omitempty,omitzero"` -} - -// +kubebuilder:object:root=true - -// VPCList contains a list of VPCs -type VPCList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []VPC `json:"items"` -} - -func init() { - SchemeBuilder.Register(&VPC{}, &VPCList{}) -} diff --git a/pkg/apis/v1alpha/vpcattachment_types.go b/pkg/apis/v1alpha/vpcattachment_types.go deleted file mode 100644 index a97e93c..0000000 --- a/pkg/apis/v1alpha/vpcattachment_types.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2025 Datum Cloud, Inc. -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package v1alpha - -import ( - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const VPCAttachmentAnnotation = "k8s.v1alpha.galactic.datumapis.com/vpc-attachment" - -// VPCAttachmentSpec defines the desired state of VPCAttachment -type VPCAttachmentSpec struct { - // VPC this attachment belongs to. - // +required - VPC corev1.ObjectReference `json:"vpc"` - - // Interface defines the network interface configuration. - // +required - Interface VPCAttachmentInterface `json:"interface"` - - // Routes defines additional routing entries for the VPCAttachment. - // +optional - Routes []VPCAttachmentRoute `json:"routes,omitempty"` -} - -// VPCAttachmentInterface defines the network interface details. -type VPCAttachmentInterface struct { - // Name of the interface (e.g., eth0). - // +required - // +default:value="galactic0" - Name string `json:"name"` - - // A list of IPv4 or IPv6 addresses associated with the interface. - // +kubebuilder:validation:MinItems=1 - // +required - Addresses []string `json:"addresses"` -} - -// VPCAttachmentRoute defines a routing entry for the VPCAttachment. -type VPCAttachmentRoute struct { - // IPv4 or IPv6 destination network in CIDR notation. - // +required - Destination string `json:"destination"` - - // Via is the next hop address. - // +optional - Via string `json:"via"` -} - -// VPCAttachmentStatus defines the observed state of VPCAttachment. -type VPCAttachmentStatus struct { - // Indicates whether the VPCAttachment is ready for use - // +required - // +default:value=false - Ready bool `json:"ready,omitempty"` - - // A unique identifier assigned to this VPCAttachment - // +optional - Identifier string `json:"identifier,omitempty"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status - -// VPCAttachment is the Schema for the vpcattachments API -type VPCAttachment struct { - metav1.TypeMeta `json:",inline"` - - // metadata is a standard object metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty,omitzero"` - - // spec defines the desired state of VPCAttachment - // +required - Spec VPCAttachmentSpec `json:"spec"` - - // status defines the observed state of VPCAttachment - // +optional - Status VPCAttachmentStatus `json:"status,omitempty,omitzero"` -} - -// +kubebuilder:object:root=true - -// VPCAttachmentList contains a list of VPCAttachments -type VPCAttachmentList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []VPCAttachment `json:"items"` -} - -func init() { - SchemeBuilder.Register(&VPCAttachment{}, &VPCAttachmentList{}) -} diff --git a/pkg/apis/v1alpha/zz_generated.deepcopy.go b/pkg/apis/v1alpha/zz_generated.deepcopy.go deleted file mode 100644 index 57b6a4b..0000000 --- a/pkg/apis/v1alpha/zz_generated.deepcopy.go +++ /dev/null @@ -1,250 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1alpha - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPC) DeepCopyInto(out *VPC) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPC. -func (in *VPC) DeepCopy() *VPC { - if in == nil { - return nil - } - out := new(VPC) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *VPC) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCAttachment) DeepCopyInto(out *VPCAttachment) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCAttachment. -func (in *VPCAttachment) DeepCopy() *VPCAttachment { - if in == nil { - return nil - } - out := new(VPCAttachment) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *VPCAttachment) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCAttachmentInterface) DeepCopyInto(out *VPCAttachmentInterface) { - *out = *in - if in.Addresses != nil { - in, out := &in.Addresses, &out.Addresses - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCAttachmentInterface. -func (in *VPCAttachmentInterface) DeepCopy() *VPCAttachmentInterface { - if in == nil { - return nil - } - out := new(VPCAttachmentInterface) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCAttachmentList) DeepCopyInto(out *VPCAttachmentList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]VPCAttachment, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCAttachmentList. -func (in *VPCAttachmentList) DeepCopy() *VPCAttachmentList { - if in == nil { - return nil - } - out := new(VPCAttachmentList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *VPCAttachmentList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCAttachmentRoute) DeepCopyInto(out *VPCAttachmentRoute) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCAttachmentRoute. -func (in *VPCAttachmentRoute) DeepCopy() *VPCAttachmentRoute { - if in == nil { - return nil - } - out := new(VPCAttachmentRoute) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCAttachmentSpec) DeepCopyInto(out *VPCAttachmentSpec) { - *out = *in - out.VPC = in.VPC - in.Interface.DeepCopyInto(&out.Interface) - if in.Routes != nil { - in, out := &in.Routes, &out.Routes - *out = make([]VPCAttachmentRoute, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCAttachmentSpec. -func (in *VPCAttachmentSpec) DeepCopy() *VPCAttachmentSpec { - if in == nil { - return nil - } - out := new(VPCAttachmentSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCAttachmentStatus) DeepCopyInto(out *VPCAttachmentStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCAttachmentStatus. -func (in *VPCAttachmentStatus) DeepCopy() *VPCAttachmentStatus { - if in == nil { - return nil - } - out := new(VPCAttachmentStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCList) DeepCopyInto(out *VPCList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]VPC, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCList. -func (in *VPCList) DeepCopy() *VPCList { - if in == nil { - return nil - } - out := new(VPCList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *VPCList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCSpec) DeepCopyInto(out *VPCSpec) { - *out = *in - if in.Networks != nil { - in, out := &in.Networks, &out.Networks - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCSpec. -func (in *VPCSpec) DeepCopy() *VPCSpec { - if in == nil { - return nil - } - out := new(VPCSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VPCStatus) DeepCopyInto(out *VPCStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCStatus. -func (in *VPCStatus) DeepCopy() *VPCStatus { - if in == nil { - return nil - } - out := new(VPCStatus) - in.DeepCopyInto(out) - return out -} From cd2e80e7f85ebabcc8ec48ad6d51ec24fdce08c1 Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Fri, 22 May 2026 18:05:11 -0400 Subject: [PATCH 2/3] ci: Remove operator-specific jobs and steps from workflows - Remove test-operator job (envtest + controller tests are gone) - Remove make manifests generate steps from build and release jobs - Update test-unit to only run pkg/common/util tests - Remove test-operator from test-e2e needs - Remove VPC/VPCAttachment CRD verification and sample apply steps from e2e - Remove make manifests generate from release workflow Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.yml | 51 +++-------------------------------- .github/workflows/release.yml | 3 --- 2 files changed, 4 insertions(+), 50 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80d1e9b..4acb4ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,6 @@ jobs: - name: Run unit tests run: | go test -v -race -coverprofile=coverage.out \ - ./internal/operator/identifier/... \ - ./internal/operator/cniconfig/... \ ./pkg/common/util/... - name: Upload coverage @@ -50,35 +48,6 @@ jobs: files: coverage.out fail_ci_if_error: false - test-operator: - name: Operator Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Generate manifests - run: make manifests generate - - - name: Install envtest - run: go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest - - - name: Run operator tests - run: | - KUBEBUILDER_ASSETS=$(setup-envtest use 1.31.0 -p path) - export KUBEBUILDER_ASSETS - echo "KUBEBUILDER_ASSETS=$KUBEBUILDER_ASSETS" - go test -v -race -coverprofile=coverage-operator.out ./internal/operator/... - - - name: Upload coverage - uses: codecov/codecov-action@v6 - with: - files: coverage-operator.out - fail_ci_if_error: false - build: name: Build runs-on: ubuntu-latest @@ -89,9 +58,6 @@ jobs: with: go-version: ${{ env.GO_VERSION }} - - name: Generate manifests - run: make manifests generate - - name: Build binary run: make build @@ -122,7 +88,7 @@ jobs: test-e2e: name: E2E Tests runs-on: ubuntu-latest - needs: [lint, test-unit, test-operator, build] + needs: [lint, test-unit, build] if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') steps: - uses: actions/checkout@v6 @@ -149,23 +115,14 @@ jobs: - name: Install CRDs run: make install - - name: Deploy operator + - name: Deploy agent run: | make deploy IMG=galactic:e2e - kubectl -n galactic-system wait --for=condition=available deployment/galactic-controller-manager --timeout=120s + kubectl -n galactic-operator-system wait --for=condition=available deployment/galactic-operator-controller-manager --timeout=120s - name: Verify CRDs run: | - kubectl get crd vpcs.galactic.datumapis.com - kubectl get crd vpcattachments.galactic.datumapis.com - - - name: Create test resources - run: | - kubectl apply -f config/samples/galactic_v1alpha_vpc.yaml - kubectl apply -f config/samples/galactic_v1alpha_vpcattachment.yaml - sleep 5 - kubectl get vpc - kubectl get vpcattachment + kubectl get crd network-attachment-definitions.k8s.cni.cncf.io - name: Cleanup if: always() diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2307e1f..3731ca6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,9 +24,6 @@ jobs: with: go-version: '1.24' - - name: Generate manifests - run: make manifests generate - - name: Log in to Container Registry uses: docker/login-action@v4 with: From 4f95e586a08ac1583492187dacce6e7c6dbafc87 Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Fri, 22 May 2026 18:10:43 -0400 Subject: [PATCH 3/3] ci: Remove controller-manager deployment artifacts and fix workflow gaps - Remove config/manager/ (deployment ran /galactic operator which no longer exists) - Remove config/default/metrics_service.yaml and manager_metrics_patch.yaml - Update config/default/kustomization.yaml to only include crd and rbac - Remove make deploy, undeploy, build-installer targets from Makefile - Remove make build-installer step and dist/install.yaml from release workflow - Remove make deploy and controller-manager wait from e2e job - Remove ginkgolinter from golangci config (no Ginkgo tests remain) - Remove dead api/* lll exclusion rule from golangci config Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.yml | 5 -- .github/workflows/release.yml | 6 -- .golangci.yml | 4 - Makefile | 15 ---- config/default/kustomization.yaml | 92 +------------------- config/default/manager_metrics_patch.yaml | 4 - config/default/metrics_service.yaml | 18 ---- config/manager/kustomization.yaml | 8 -- config/manager/manager.yaml | 100 ---------------------- 9 files changed, 1 insertion(+), 251 deletions(-) delete mode 100644 config/default/manager_metrics_patch.yaml delete mode 100644 config/default/metrics_service.yaml delete mode 100644 config/manager/kustomization.yaml delete mode 100644 config/manager/manager.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4acb4ce..96c4196 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,11 +115,6 @@ jobs: - name: Install CRDs run: make install - - name: Deploy agent - run: | - make deploy IMG=galactic:e2e - kubectl -n galactic-operator-system wait --for=condition=available deployment/galactic-operator-controller-manager --timeout=120s - - name: Verify CRDs run: | kubectl get crd network-attachment-definitions.k8s.cni.cncf.io diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3731ca6..82aac12 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,13 +61,7 @@ jobs: GIT_TREE_STATE=clean BUILD_DATE=${{ github.event.repository.updated_at }} - - name: Generate install manifest - run: | - make build-installer IMG=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} - - name: Create Release uses: softprops/action-gh-release@v3 with: generate_release_notes: true - files: | - dist/install.yaml diff --git a/.golangci.yml b/.golangci.yml index 21045c1..dcbe02c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,7 +7,6 @@ linters: - copyloopvar - dupl - errcheck - - ginkgolinter - goconst - gocyclo - govet @@ -29,9 +28,6 @@ linters: exclusions: generated: lax rules: - - linters: - - lll - path: api/* - linters: - dupl - lll diff --git a/Makefile b/Makefile index 4e00ea9..9fadaf1 100644 --- a/Makefile +++ b/Makefile @@ -136,12 +136,6 @@ docker-buildx: ## Build and push docker image for the unified binary for cross-p - $(CONTAINER_TOOL) buildx rm galactic-builder rm build/Dockerfile.cross -.PHONY: build-installer -build-installer: kustomize ## Generate a consolidated YAML with CRDs and deployment. - mkdir -p dist - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default > dist/install.yaml - ##@ Deployment ifndef ignore-not-found @@ -156,15 +150,6 @@ install: kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/con uninstall: kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. $(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - -.PHONY: deploy -deploy: kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f - - -.PHONY: undeploy -undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - ##@ Cleanup .PHONY: clean diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 95df19b..5137d77 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -8,100 +8,10 @@ namespace: galactic-operator-system # field above. namePrefix: galactic-operator- -# Labels to add to all resources and selectors. -#labels: -#- includeSelectors: true -# pairs: -# someName: someValue - resources: - ../crd - ../rbac -- ../manager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus -# [METRICS] Expose the controller manager metrics service. -- metrics_service.yaml -# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. -# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. -# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will -# be able to communicate with the Webhook Server. +# [NETWORK POLICY] Protect the /metrics endpoint with NetworkPolicy. #- ../network-policy - -# Uncomment the patches line if you enable Metrics -patches: -# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. -# More info: https://book.kubebuilder.io/reference/metrics -- path: manager_metrics_patch.yaml - target: - kind: Deployment - -# Uncomment the patches line if you enable Metrics and CertManager -# [METRICS-WITH-CERTS] To enable metrics protected with certManager, uncomment the following line. -# This patch will protect the metrics with certManager self-signed certs. -#- path: cert_metrics_manager_patch.yaml -# target: -# kind: Deployment - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -# Uncomment the following replacements to add the cert-manager CA injection annotations -replacements: -# - source: # Uncomment the following block to enable certificates for metrics -# kind: Service -# version: v1 -# name: controller-manager-metrics-service -# fieldPath: metadata.name -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: metrics-certs -# fieldPaths: -# - spec.dnsNames.0 -# - spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 0 -# create: true -# - select: # Uncomment the following to set the Service name for TLS config in Prometheus ServiceMonitor -# kind: ServiceMonitor -# group: monitoring.coreos.com -# version: v1 -# name: controller-manager-metrics-monitor -# fieldPaths: -# - spec.endpoints.0.tlsConfig.serverName -# options: -# delimiter: '.' -# index: 0 -# create: true - -# - source: -# kind: Service -# version: v1 -# name: controller-manager-metrics-service -# fieldPath: metadata.namespace -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: metrics-certs -# fieldPaths: -# - spec.dnsNames.0 -# - spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 1 -# create: true -# - select: # Uncomment the following to set the Service namespace for TLS in Prometheus ServiceMonitor -# kind: ServiceMonitor -# group: monitoring.coreos.com -# version: v1 -# name: controller-manager-metrics-monitor -# fieldPaths: -# - spec.endpoints.0.tlsConfig.serverName -# options: -# delimiter: '.' -# index: 1 -# create: true diff --git a/config/default/manager_metrics_patch.yaml b/config/default/manager_metrics_patch.yaml deleted file mode 100644 index 2aaef65..0000000 --- a/config/default/manager_metrics_patch.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# This patch adds the args to allow exposing the metrics endpoint using HTTPS -- op: add - path: /spec/template/spec/containers/0/args/0 - value: --metrics-bind-address=:8443 diff --git a/config/default/metrics_service.yaml b/config/default/metrics_service.yaml deleted file mode 100644 index 8d4c950..0000000 --- a/config/default/metrics_service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-service - namespace: system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: 8443 - selector: - control-plane: controller-manager - app.kubernetes.io/name: galactic-operator diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml deleted file mode 100644 index ad13e96..0000000 --- a/config/manager/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -resources: -- manager.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: controller - newTag: latest diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml deleted file mode 100644 index 5792355..0000000 --- a/config/manager/manager.yaml +++ /dev/null @@ -1,100 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize - name: system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - control-plane: controller-manager - app.kubernetes.io/name: galactic-operator - app.kubernetes.io/managed-by: kustomize -spec: - selector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: galactic-operator - replicas: 1 - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - app.kubernetes.io/name: galactic-operator - spec: - # TODO(user): Uncomment the following code to configure the nodeAffinity expression - # according to the platforms which are supported by your solution. - # It is considered best practice to support multiple architectures. You can - # build your manager image using the makefile target docker-buildx. - # affinity: - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/arch - # operator: In - # values: - # - amd64 - # - arm64 - # - ppc64le - # - s390x - # - key: kubernetes.io/os - # operator: In - # values: - # - linux - securityContext: - # Projects are configured by default to adhere to the "restricted" Pod Security Standards. - # This ensures that deployments meet the highest security requirements for Kubernetes. - # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - containers: - - command: - - /galactic - - operator - args: - - --leader-elect - - --health-probe-bind-address=:8081 - image: ghcr.io/datum-cloud/galactic:latest - name: manager - ports: [] - securityContext: - readOnlyRootFilesystem: true - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - # TODO(user): Configure the resources accordingly based on the project requirements. - # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - volumeMounts: [] - volumes: [] - serviceAccountName: controller-manager - terminationGracePeriodSeconds: 10