diff --git a/Dockerfile b/Dockerfile index 0bd14247..94e3141c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,13 +10,17 @@ COPY go.sum go.sum RUN go mod download # Copy the go source -COPY main.go main.go -COPY apis/ apis/ -COPY controllers/ controllers/ -COPY internal/ internal/ +COPY cmd/ cmd/ +COPY api/ api/ +COPY internal/controllers internal/controllers +COPY internal/harbor internal/harbor +COPY internal/helpers internal/helpers +COPY internal/messenger internal/messenger +COPY internal/metrics internal/metrics +COPY internal/utilities internal/utilities # Build -RUN CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} GO111MODULE=on go build -a -o manager main.go +RUN CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} GO111MODULE=on go build -a -o manager cmd/main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/Makefile b/Makefile index 8cb005a3..960f60cb 100644 --- a/Makefile +++ b/Makefile @@ -62,12 +62,12 @@ test: manifests generate fmt vet envtest ## Run tests. # Build manager binary .PHONY: manager manager: generate fmt vet - go build -o bin/manager main.go + go build -o bin/manager cmd/main.go # Run against the configured Kubernetes cluster in ~/.kube/config .PHONY: run run: generate fmt vet manifests - go run ./main.go --controller-namespace=${CONTROLLER_NAMESPACE} + go run ./cmd/main.go --controller-namespace=${CONTROLLER_NAMESPACE} # Install CRDs into a cluster .PHONY: install @@ -130,7 +130,7 @@ ifeq (, $(shell which controller-gen)) CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ cd $$CONTROLLER_GEN_TMP_DIR ;\ go mod init tmp ;\ - go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.2 ;\ + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.5 ;\ rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ } CONTROLLER_GEN=$(GOBIN)/controller-gen diff --git a/PROJECT b/PROJECT index 6bcbae60..fdd90e25 100644 --- a/PROJECT +++ b/PROJECT @@ -1,17 +1,43 @@ domain: lagoon.sh -multigroup: true +layout: +- go.kubebuilder.io/v3 +projectName: remote-controller repo: github.com/uselagoon/remote-controller resources: -- group: crd +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: lagoon.sh + group: crd kind: LagoonBuild + path: remote-controller/api/lagoon/v1beta2 version: v1beta2 -- group: crd +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: lagoon.sh + group: crd kind: LagoonTask + path: remote-controller/api/lagoon/v1beta2 version: v1beta2 -- group: crd +- api: + crdVersion: v1 + namespaced: true + controller: false + domain: lagoon.sh + group: crd kind: LagoonBuild + path: remote-controller/api/lagoon/v1beta1 version: v1beta1 -- group: crd +- api: + crdVersion: v1 + namespaced: true + controller: false + domain: lagoon.sh + group: crd kind: LagoonTask + path: remote-controller/api/lagoon/v1beta1 version: v1beta1 -version: "2" +version: "3" \ No newline at end of file diff --git a/apis/lagoon/v1beta1/groupversion_info.go b/api/lagoon/v1beta1/groupversion_info.go similarity index 100% rename from apis/lagoon/v1beta1/groupversion_info.go rename to api/lagoon/v1beta1/groupversion_info.go diff --git a/apis/lagoon/v1beta1/helpers_test.go b/api/lagoon/v1beta1/helpers_test.go similarity index 100% rename from apis/lagoon/v1beta1/helpers_test.go rename to api/lagoon/v1beta1/helpers_test.go diff --git a/apis/lagoon/v1beta1/lagoonbuild_helpers.go b/api/lagoon/v1beta1/lagoonbuild_helpers.go similarity index 100% rename from apis/lagoon/v1beta1/lagoonbuild_helpers.go rename to api/lagoon/v1beta1/lagoonbuild_helpers.go diff --git a/apis/lagoon/v1beta1/lagoonbuild_types.go b/api/lagoon/v1beta1/lagoonbuild_types.go similarity index 100% rename from apis/lagoon/v1beta1/lagoonbuild_types.go rename to api/lagoon/v1beta1/lagoonbuild_types.go diff --git a/apis/lagoon/v1beta1/lagoonmessaging_types.go b/api/lagoon/v1beta1/lagoonmessaging_types.go similarity index 100% rename from apis/lagoon/v1beta1/lagoonmessaging_types.go rename to api/lagoon/v1beta1/lagoonmessaging_types.go diff --git a/apis/lagoon/v1beta1/lagoontask_helpers.go b/api/lagoon/v1beta1/lagoontask_helpers.go similarity index 100% rename from apis/lagoon/v1beta1/lagoontask_helpers.go rename to api/lagoon/v1beta1/lagoontask_helpers.go diff --git a/apis/lagoon/v1beta1/lagoontask_types.go b/api/lagoon/v1beta1/lagoontask_types.go similarity index 100% rename from apis/lagoon/v1beta1/lagoontask_types.go rename to api/lagoon/v1beta1/lagoontask_types.go diff --git a/apis/lagoon/v1beta1/zz_generated.deepcopy.go b/api/lagoon/v1beta1/zz_generated.deepcopy.go similarity index 100% rename from apis/lagoon/v1beta1/zz_generated.deepcopy.go rename to api/lagoon/v1beta1/zz_generated.deepcopy.go diff --git a/apis/lagoon/v1beta2/groupversion_info.go b/api/lagoon/v1beta2/groupversion_info.go similarity index 100% rename from apis/lagoon/v1beta2/groupversion_info.go rename to api/lagoon/v1beta2/groupversion_info.go diff --git a/apis/lagoon/v1beta2/helpers_test.go b/api/lagoon/v1beta2/helpers_test.go similarity index 100% rename from apis/lagoon/v1beta2/helpers_test.go rename to api/lagoon/v1beta2/helpers_test.go diff --git a/apis/lagoon/v1beta2/lagoonbuild_helpers.go b/api/lagoon/v1beta2/lagoonbuild_helpers.go similarity index 100% rename from apis/lagoon/v1beta2/lagoonbuild_helpers.go rename to api/lagoon/v1beta2/lagoonbuild_helpers.go diff --git a/apis/lagoon/v1beta2/lagoonbuild_types.go b/api/lagoon/v1beta2/lagoonbuild_types.go similarity index 100% rename from apis/lagoon/v1beta2/lagoonbuild_types.go rename to api/lagoon/v1beta2/lagoonbuild_types.go diff --git a/apis/lagoon/v1beta2/lagoontask_helpers.go b/api/lagoon/v1beta2/lagoontask_helpers.go similarity index 100% rename from apis/lagoon/v1beta2/lagoontask_helpers.go rename to api/lagoon/v1beta2/lagoontask_helpers.go diff --git a/apis/lagoon/v1beta2/lagoontask_types.go b/api/lagoon/v1beta2/lagoontask_types.go similarity index 100% rename from apis/lagoon/v1beta2/lagoontask_types.go rename to api/lagoon/v1beta2/lagoontask_types.go diff --git a/apis/lagoon/v1beta2/zz_generated.deepcopy.go b/api/lagoon/v1beta2/zz_generated.deepcopy.go similarity index 100% rename from apis/lagoon/v1beta2/zz_generated.deepcopy.go rename to api/lagoon/v1beta2/zz_generated.deepcopy.go diff --git a/main.go b/cmd/main.go similarity index 96% rename from main.go rename to cmd/main.go index 52cc773b..09831d0a 100644 --- a/main.go +++ b/cmd/main.go @@ -35,21 +35,21 @@ import ( "github.com/uselagoon/remote-controller/internal/harbor" "github.com/uselagoon/remote-controller/internal/helpers" - "github.com/uselagoon/remote-controller/internal/metrics" "github.com/uselagoon/remote-controller/internal/utilities/deletions" "github.com/uselagoon/remote-controller/internal/utilities/pruner" cron "gopkg.in/robfig/cron.v2" + "sigs.k8s.io/controller-runtime/pkg/metrics/filters" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" "github.com/hashicorp/golang-lru/v2/expirable" k8upv1 "github.com/k8up-io/k8up/v2/api/v1" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" - lagoonv1beta2 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" - harborctrl "github.com/uselagoon/remote-controller/controllers/harbor" - lagoonv1beta1ctrl "github.com/uselagoon/remote-controller/controllers/v1beta1" - lagoonv1beta2ctrl "github.com/uselagoon/remote-controller/controllers/v1beta2" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" + lagoonv1beta2 "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" + harborctrl "github.com/uselagoon/remote-controller/internal/controllers/harbor" + lagoonv1beta1ctrl "github.com/uselagoon/remote-controller/internal/controllers/v1beta1" + lagoonv1beta2ctrl "github.com/uselagoon/remote-controller/internal/controllers/v1beta2" "github.com/uselagoon/remote-controller/internal/messenger" k8upv1alpha1 "github.com/vshn/k8up/api/v1alpha1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -184,10 +184,10 @@ func main() { var unauthenticatedRegistry string - flag.StringVar(&metricsAddr, "metrics-addr", ":8080", - "The address the metric endpoint binds to.") - flag.BoolVar(&secureMetrics, "metrics-secure", false, - "If set the metrics endpoint is served securely") + flag.StringVar(&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.") + flag.BoolVar(&secureMetrics, "metrics-secure", true, + "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") flag.BoolVar(&enableHTTP2, "enable-http2", false, "If set, HTTP/2 will be enabled for the metrics and webhook servers") @@ -210,7 +210,7 @@ func main() { "The number of startup attempts before exiting.") flag.IntVar(&startupConnectionInterval, "startup-connection-interval-seconds", 30, "The duration between startup attempts.") - flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, + flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.") flag.BoolVar(&enableMQ, "enable-message-queue", true, "Enable message queue to provide updates back to Lagoon.") @@ -487,13 +487,21 @@ func main() { if !enableHTTP2 { tlsOpts = append(tlsOpts, disableHTTP2) } + metricsServerOptions := metricsserver.Options{ + BindAddress: metricsAddr, + SecureServing: secureMetrics, + TLSOpts: tlsOpts, + } + if secureMetrics { + // FilterProvider is used to protect the metrics endpoint with authn/authz. + // These configurations ensure that only authorized users and service accounts + // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: + // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/filters#WithAuthenticationAndAuthorization + metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - Metrics: metricsserver.Options{ - BindAddress: metricsAddr, - SecureServing: secureMetrics, - TLSOpts: tlsOpts, - }, + Scheme: scheme, + Metrics: metricsServerOptions, LeaderElection: enableLeaderElection, LeaderElectionID: leaderElectionID, }) @@ -1009,10 +1017,6 @@ func main() { } // +kubebuilder:scaffold:builder - setupLog.Info("starting lagoon metrics server") - m := metrics.NewServer(setupLog, ":9912") - defer m.Shutdown(context.Background()) - setupLog.Info("starting manager") if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { setupLog.Error(err, "problem running manager") diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index e639c738..60d17e40 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -49,6 +49,8 @@ resources: - ../crd - ../rbac - ../manager +# [METRICS] Expose the controller manager metrics service. +- metrics_service.yaml patches: - path: envs.yaml - path: manager_auth_proxy_patch.yaml diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml index ae167ed4..567b1d51 100644 --- a/config/default/manager_auth_proxy_patch.yaml +++ b/config/default/manager_auth_proxy_patch.yaml @@ -9,20 +9,10 @@ spec: template: spec: containers: - - name: kube-rbac-proxy - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.4.1 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=10" - ports: - - containerPort: 8443 - name: https - name: manager args: - - "--metrics-addr=127.0.0.1:8080" - - "--enable-leader-election" + - "--metrics-bind-address=:8443" + - "--leader-elect" - "--build-pod-cleanup-cron=*/1 * * * *" - "--task-pod-cleanup-cron=*/1 * * * *" - "--harbor-credential-cron=*/1 * * * *" @@ -34,3 +24,6 @@ spec: - "--enable-deprecated-apis" - "--lagoon-feature-flag-support-k8upv2" - "--skip-tls-verify" + ports: + - containerPort: 8443 + name: https diff --git a/config/rbac/auth_proxy_service.yaml b/config/default/metrics_service.yaml similarity index 73% rename from config/rbac/auth_proxy_service.yaml rename to config/default/metrics_service.yaml index 6cf656be..b6e338a6 100644 --- a/config/rbac/auth_proxy_service.yaml +++ b/config/default/metrics_service.yaml @@ -9,6 +9,7 @@ spec: ports: - name: https port: 8443 - targetPort: https + protocol: TCP + targetPort: 8443 selector: - control-plane: controller-manager + control-plane: controller-manager \ No newline at end of file diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 93489562..d31e119c 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -26,11 +26,12 @@ spec: - command: - /manager args: - - --enable-leader-election + - --leader-elect image: controller:latest name: manager resources: requests: cpu: 100m - memory: 20Mi + memory: 400Mi + serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index 817f1fe6..119be019 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -1,11 +1,21 @@ resources: +# All RBAC will be applied under this service account in +# the deployment namespace. You may comment out this resource +# if your manager will use a service account that exists at +# runtime. Be sure to update RoleBinding and ClusterRoleBinding +# subjects if changing service account names. +- service_account.yaml - role.yaml - role_binding.yaml - leader_election_role.yaml - leader_election_role_binding.yaml -# Comment the following 3 lines if you want to disable -# the auth proxy (https://github.com/brancz/kube-rbac-proxy) -# which protects your /metrics endpoint. -- auth_proxy_service.yaml -- auth_proxy_role.yaml -- auth_proxy_role_binding.yaml +# The following RBAC configurations are used to protect +# the metrics endpoint with authn/authz. These configurations +# ensure that only authorized users and service accounts +# can access the metrics endpoint. Comment the following +# permissions if you want to disable this protection. +# More info: https://book.kubebuilder.io/reference/metrics.html +- metrics_auth_role.yaml +- metrics_auth_role_binding.yaml +- metrics_reader_role.yaml +- metrics_reader_role_binding.yaml \ No newline at end of file diff --git a/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml index eaa79158..1e4984e7 100644 --- a/config/rbac/leader_election_role.yaml +++ b/config/rbac/leader_election_role.yaml @@ -17,16 +17,21 @@ rules: - patch - delete - apiGroups: - - "" + - coordination.k8s.io resources: - - configmaps/status + - leases verbs: - get + - list + - watch + - create - update - patch + - delete - apiGroups: - "" resources: - events verbs: - create + - patch \ No newline at end of file diff --git a/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml index eed16906..4a7819cf 100644 --- a/config/rbac/leader_election_role_binding.yaml +++ b/config/rbac/leader_election_role_binding.yaml @@ -8,5 +8,5 @@ roleRef: name: leader-election-role subjects: - kind: ServiceAccount - name: default - namespace: system + name: controller-manager + namespace: system \ No newline at end of file diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/metrics_auth_role.yaml similarity index 55% rename from config/rbac/auth_proxy_role.yaml rename to config/rbac/metrics_auth_role.yaml index 618f5e41..5a503734 100644 --- a/config/rbac/auth_proxy_role.yaml +++ b/config/rbac/metrics_auth_role.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: proxy-role + name: metrics-auth-role rules: - apiGroups: ["authentication.k8s.io"] resources: @@ -11,3 +11,15 @@ rules: resources: - subjectaccessreviews verbs: ["create"] +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create \ No newline at end of file diff --git a/config/rbac/metrics_auth_role_binding.yaml b/config/rbac/metrics_auth_role_binding.yaml new file mode 100644 index 00000000..c59a8024 --- /dev/null +++ b/config/rbac/metrics_auth_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: metrics-auth-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system \ No newline at end of file diff --git a/config/rbac/metrics_reader_role.yaml b/config/rbac/metrics_reader_role.yaml new file mode 100644 index 00000000..50fbca54 --- /dev/null +++ b/config/rbac/metrics_reader_role.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get \ No newline at end of file diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/metrics_reader_role_binding.yaml similarity index 62% rename from config/rbac/auth_proxy_role_binding.yaml rename to config/rbac/metrics_reader_role_binding.yaml index 48ed1e4b..2d14de4d 100644 --- a/config/rbac/auth_proxy_role_binding.yaml +++ b/config/rbac/metrics_reader_role_binding.yaml @@ -1,12 +1,12 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: proxy-rolebinding + name: metrics-reader-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: proxy-role + name: metrics-reader subjects: - kind: ServiceAccount - name: default - namespace: system + name: controller-manager + namespace: system \ No newline at end of file diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml index 8f265870..2070ede4 100644 --- a/config/rbac/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -8,5 +8,5 @@ roleRef: name: manager-role subjects: - kind: ServiceAccount - name: default + name: controller-manager namespace: system diff --git a/config/rbac/service_account.yaml b/config/rbac/service_account.yaml new file mode 100644 index 00000000..d9ceb1cd --- /dev/null +++ b/config/rbac/service_account.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: project-v4 + app.kubernetes.io/managed-by: kustomize + name: controller-manager + namespace: system \ No newline at end of file diff --git a/go.mod b/go.mod index bc390b23..f248368a 100644 --- a/go.mod +++ b/go.mod @@ -27,18 +27,22 @@ require ( k8s.io/apiextensions-apiserver v0.31.1 k8s.io/apimachinery v0.31.1 k8s.io/client-go v0.31.1 - sigs.k8s.io/controller-runtime v0.19.0 + sigs.k8s.io/controller-runtime v0.19.2 ) require ( github.com/NeowayLabs/wabbit v0.0.0-20210927194032-73ad61d1620e // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -58,18 +62,20 @@ require ( github.com/goharbor/harbor/src v0.0.0-20230220075213-6015b3efa7d0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/cel-go v0.20.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/guregu/null v4.0.0+incompatible // indirect github.com/imdario/mergo v0.3.13 // 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/matryer/try v0.0.0-20161228173917-9ac251b645a2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/term v0.5.0 // 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 @@ -82,30 +88,44 @@ require ( github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rabbitmq/amqp091-go v1.7.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect golang.org/x/term v0.21.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiserver v0.31.1 // indirect + k8s.io/component-base v0.31.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 66618cd0..15b24a06 100644 --- a/go.sum +++ b/go.sum @@ -124,6 +124,8 @@ github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -149,6 +151,8 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +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/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bombsimon/wsl v1.2.5/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= @@ -159,6 +163,8 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= @@ -328,6 +334,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -403,6 +410,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/firepear/qsplit/v2 v2.5.0/go.mod h1:Q65ZpyUdvAUkXISeeNtA3DPlDwEn9mHU/kzTtPUxmKQ= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -657,6 +666,8 @@ github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= +github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -734,6 +745,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpg github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/guregu/null v4.0.0+incompatible h1:4zw0ckM7ECd6FNNddc3Fu4aty9nTlpkkzH7dPn4/4Gw= github.com/guregu/null v4.0.0+incompatible/go.mod h1:ePGpQaN9cw0tj45IR5E5ehMvsFlLlQZAkkOXZurJ3NM= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -791,6 +804,8 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= @@ -1125,6 +1140,7 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= @@ -1173,6 +1189,8 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1184,6 +1202,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -1308,6 +1327,8 @@ go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUz go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -1315,7 +1336,11 @@ go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIj go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= @@ -1333,6 +1358,8 @@ go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+ go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1860,6 +1887,10 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1892,6 +1923,8 @@ google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5 google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -2007,6 +2040,8 @@ k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU= k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= +k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c= +k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM= k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk= k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= k8s.io/client-go v0.18.10/go.mod h1:XBkFAqPrzqfwmGkV5ac+mlgBpWcz5TkhLw2808q8C3c= @@ -2029,6 +2064,8 @@ k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGw k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= k8s.io/component-base v0.21.3/go.mod h1:kkuhtfEHeZM6LkX0saqSK8PbdO7A0HigUngmhhrwfGQ= k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= +k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8= +k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= @@ -2088,9 +2125,11 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyz sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/controller-runtime v0.19.2 h1:3sPrF58XQEPzbE8T81TN6selQIMGbtYwuaJ6eDssDF8= +sigs.k8s.io/controller-runtime v0.19.2/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20210802150722-c0a5babc6854/go.mod h1:jqzBWjsNdxfl/cDmihB034I5aCqlfw2p24HYs3Eo4K4= sigs.k8s.io/controller-tools v0.2.2/go.mod h1:8SNGuj163x/sMwydREj7ld5mIMJu1cDanIfnx6xsU70= sigs.k8s.io/controller-tools v0.5.0/go.mod h1:JTsstrMpxs+9BUj6eGuAaEb6SDSPTeVtUyp0jmnAM/I= diff --git a/controllers/harbor/harborcredential_controller.go b/internal/controllers/harbor/harborcredential_controller.go similarity index 100% rename from controllers/harbor/harborcredential_controller.go rename to internal/controllers/harbor/harborcredential_controller.go diff --git a/controllers/harbor/predicates.go b/internal/controllers/harbor/predicates.go similarity index 100% rename from controllers/harbor/predicates.go rename to internal/controllers/harbor/predicates.go diff --git a/controllers/v1beta1/build_controller.go b/internal/controllers/v1beta1/build_controller.go similarity index 99% rename from controllers/v1beta1/build_controller.go rename to internal/controllers/v1beta1/build_controller.go index 297d8955..9a523bee 100644 --- a/controllers/v1beta1/build_controller.go +++ b/internal/controllers/v1beta1/build_controller.go @@ -28,7 +28,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/harbor" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/messenger" diff --git a/controllers/v1beta1/build_deletionhandlers.go b/internal/controllers/v1beta1/build_deletionhandlers.go similarity index 99% rename from controllers/v1beta1/build_deletionhandlers.go rename to internal/controllers/v1beta1/build_deletionhandlers.go index c7f7292b..3b85dd8a 100644 --- a/controllers/v1beta1/build_deletionhandlers.go +++ b/internal/controllers/v1beta1/build_deletionhandlers.go @@ -12,7 +12,7 @@ import ( "github.com/go-logr/logr" "github.com/uselagoon/machinery/api/schema" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/helpers" "gopkg.in/matryer/try.v1" corev1 "k8s.io/api/core/v1" diff --git a/controllers/v1beta1/build_helpers.go b/internal/controllers/v1beta1/build_helpers.go similarity index 99% rename from controllers/v1beta1/build_helpers.go rename to internal/controllers/v1beta1/build_helpers.go index 59a751eb..56ed05f2 100644 --- a/controllers/v1beta1/build_helpers.go +++ b/internal/controllers/v1beta1/build_helpers.go @@ -17,7 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/go-logr/logr" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/harbor" "github.com/uselagoon/remote-controller/internal/helpers" ) diff --git a/controllers/v1beta1/build_helpers_test.go b/internal/controllers/v1beta1/build_helpers_test.go similarity index 98% rename from controllers/v1beta1/build_helpers_test.go rename to internal/controllers/v1beta1/build_helpers_test.go index 5692de32..e9c6d4aa 100644 --- a/controllers/v1beta1/build_helpers_test.go +++ b/internal/controllers/v1beta1/build_helpers_test.go @@ -5,7 +5,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/helpers" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/controllers/v1beta1/build_qoshandler.go b/internal/controllers/v1beta1/build_qoshandler.go similarity index 99% rename from controllers/v1beta1/build_qoshandler.go rename to internal/controllers/v1beta1/build_qoshandler.go index 7a7016ab..d7cc22bc 100644 --- a/controllers/v1beta1/build_qoshandler.go +++ b/internal/controllers/v1beta1/build_qoshandler.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/go-logr/logr" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/helpers" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" diff --git a/controllers/v1beta1/build_standardhandler.go b/internal/controllers/v1beta1/build_standardhandler.go similarity index 97% rename from controllers/v1beta1/build_standardhandler.go rename to internal/controllers/v1beta1/build_standardhandler.go index 9bcc8ca1..fd817cbb 100644 --- a/controllers/v1beta1/build_standardhandler.go +++ b/internal/controllers/v1beta1/build_standardhandler.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/go-logr/logr" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/helpers" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" diff --git a/controllers/v1beta1/podmonitor_buildhandlers.go b/internal/controllers/v1beta1/podmonitor_buildhandlers.go similarity index 99% rename from controllers/v1beta1/podmonitor_buildhandlers.go rename to internal/controllers/v1beta1/podmonitor_buildhandlers.go index 4d49a0b7..9dafde9b 100644 --- a/controllers/v1beta1/podmonitor_buildhandlers.go +++ b/internal/controllers/v1beta1/podmonitor_buildhandlers.go @@ -12,7 +12,7 @@ import ( "github.com/go-logr/logr" "github.com/uselagoon/machinery/api/schema" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/helpers" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" diff --git a/controllers/v1beta1/podmonitor_controller.go b/internal/controllers/v1beta1/podmonitor_controller.go similarity index 99% rename from controllers/v1beta1/podmonitor_controller.go rename to internal/controllers/v1beta1/podmonitor_controller.go index d0c749e7..37e884d6 100644 --- a/controllers/v1beta1/podmonitor_controller.go +++ b/internal/controllers/v1beta1/podmonitor_controller.go @@ -24,7 +24,7 @@ import ( "github.com/go-logr/logr" "github.com/hashicorp/golang-lru/v2/expirable" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/messenger" corev1 "k8s.io/api/core/v1" diff --git a/controllers/v1beta1/podmonitor_taskhandlers.go b/internal/controllers/v1beta1/podmonitor_taskhandlers.go similarity index 99% rename from controllers/v1beta1/podmonitor_taskhandlers.go rename to internal/controllers/v1beta1/podmonitor_taskhandlers.go index 8a026134..4ec1e957 100644 --- a/controllers/v1beta1/podmonitor_taskhandlers.go +++ b/internal/controllers/v1beta1/podmonitor_taskhandlers.go @@ -12,7 +12,7 @@ import ( "github.com/go-logr/logr" "github.com/uselagoon/machinery/api/schema" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/helpers" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/controllers/v1beta1/predicates.go b/internal/controllers/v1beta1/predicates.go similarity index 100% rename from controllers/v1beta1/predicates.go rename to internal/controllers/v1beta1/predicates.go diff --git a/controllers/v1beta1/suite_test.go b/internal/controllers/v1beta1/suite_test.go similarity index 92% rename from controllers/v1beta1/suite_test.go rename to internal/controllers/v1beta1/suite_test.go index 8a0c3f7c..8e6699b1 100644 --- a/controllers/v1beta1/suite_test.go +++ b/internal/controllers/v1beta1/suite_test.go @@ -22,7 +22,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" @@ -50,7 +50,7 @@ var _ = BeforeSuite(func(done Done) { By("bootstrapping test environment") testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, } var err error diff --git a/controllers/v1beta1/task_controller.go b/internal/controllers/v1beta1/task_controller.go similarity index 99% rename from controllers/v1beta1/task_controller.go rename to internal/controllers/v1beta1/task_controller.go index 12d2676f..b9572290 100644 --- a/controllers/v1beta1/task_controller.go +++ b/internal/controllers/v1beta1/task_controller.go @@ -31,7 +31,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" "github.com/uselagoon/remote-controller/internal/helpers" ) diff --git a/controllers/v1beta1/task_helpers.go b/internal/controllers/v1beta1/task_helpers.go similarity index 100% rename from controllers/v1beta1/task_helpers.go rename to internal/controllers/v1beta1/task_helpers.go diff --git a/controllers/v1beta2/build_controller.go b/internal/controllers/v1beta2/build_controller.go similarity index 99% rename from controllers/v1beta2/build_controller.go rename to internal/controllers/v1beta2/build_controller.go index 476228fd..438fedec 100644 --- a/controllers/v1beta2/build_controller.go +++ b/internal/controllers/v1beta2/build_controller.go @@ -28,7 +28,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/harbor" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/messenger" diff --git a/controllers/v1beta2/build_deletionhandlers.go b/internal/controllers/v1beta2/build_deletionhandlers.go similarity index 99% rename from controllers/v1beta2/build_deletionhandlers.go rename to internal/controllers/v1beta2/build_deletionhandlers.go index e9fb7f26..a227c0da 100644 --- a/controllers/v1beta2/build_deletionhandlers.go +++ b/internal/controllers/v1beta2/build_deletionhandlers.go @@ -12,7 +12,7 @@ import ( "github.com/go-logr/logr" "github.com/uselagoon/machinery/api/schema" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" "gopkg.in/matryer/try.v1" corev1 "k8s.io/api/core/v1" diff --git a/controllers/v1beta2/build_helpers.go b/internal/controllers/v1beta2/build_helpers.go similarity index 99% rename from controllers/v1beta2/build_helpers.go rename to internal/controllers/v1beta2/build_helpers.go index 9d2120ac..f71119a5 100644 --- a/controllers/v1beta2/build_helpers.go +++ b/internal/controllers/v1beta2/build_helpers.go @@ -18,7 +18,7 @@ import ( "github.com/go-logr/logr" "github.com/prometheus/client_golang/prometheus" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/harbor" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/metrics" diff --git a/controllers/v1beta2/build_helpers_test.go b/internal/controllers/v1beta2/build_helpers_test.go similarity index 98% rename from controllers/v1beta2/build_helpers_test.go rename to internal/controllers/v1beta2/build_helpers_test.go index ac8909f6..e04a7885 100644 --- a/controllers/v1beta2/build_helpers_test.go +++ b/internal/controllers/v1beta2/build_helpers_test.go @@ -5,7 +5,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/controllers/v1beta2/build_qoshandler.go b/internal/controllers/v1beta2/build_qoshandler.go similarity index 99% rename from controllers/v1beta2/build_qoshandler.go rename to internal/controllers/v1beta2/build_qoshandler.go index 555a4644..7466dc93 100644 --- a/controllers/v1beta2/build_qoshandler.go +++ b/internal/controllers/v1beta2/build_qoshandler.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/go-logr/logr" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/metrics" "k8s.io/apimachinery/pkg/types" diff --git a/controllers/v1beta2/build_standardhandler.go b/internal/controllers/v1beta2/build_standardhandler.go similarity index 97% rename from controllers/v1beta2/build_standardhandler.go rename to internal/controllers/v1beta2/build_standardhandler.go index dd893c28..16a5265b 100644 --- a/controllers/v1beta2/build_standardhandler.go +++ b/internal/controllers/v1beta2/build_standardhandler.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/go-logr/logr" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" diff --git a/controllers/v1beta2/podmonitor_buildhandlers.go b/internal/controllers/v1beta2/podmonitor_buildhandlers.go similarity index 99% rename from controllers/v1beta2/podmonitor_buildhandlers.go rename to internal/controllers/v1beta2/podmonitor_buildhandlers.go index e5619998..52f4b5ff 100644 --- a/controllers/v1beta2/podmonitor_buildhandlers.go +++ b/internal/controllers/v1beta2/podmonitor_buildhandlers.go @@ -13,7 +13,7 @@ import ( "github.com/go-logr/logr" "github.com/prometheus/client_golang/prometheus" "github.com/uselagoon/machinery/api/schema" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/metrics" "golang.org/x/text/cases" diff --git a/controllers/v1beta2/podmonitor_controller.go b/internal/controllers/v1beta2/podmonitor_controller.go similarity index 99% rename from controllers/v1beta2/podmonitor_controller.go rename to internal/controllers/v1beta2/podmonitor_controller.go index 08ce2516..6a98f255 100644 --- a/controllers/v1beta2/podmonitor_controller.go +++ b/internal/controllers/v1beta2/podmonitor_controller.go @@ -24,7 +24,7 @@ import ( "github.com/go-logr/logr" "github.com/hashicorp/golang-lru/v2/expirable" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/messenger" corev1 "k8s.io/api/core/v1" diff --git a/controllers/v1beta2/podmonitor_metrics.go b/internal/controllers/v1beta2/podmonitor_metrics.go similarity index 100% rename from controllers/v1beta2/podmonitor_metrics.go rename to internal/controllers/v1beta2/podmonitor_metrics.go diff --git a/controllers/v1beta2/podmonitor_taskhandlers.go b/internal/controllers/v1beta2/podmonitor_taskhandlers.go similarity index 99% rename from controllers/v1beta2/podmonitor_taskhandlers.go rename to internal/controllers/v1beta2/podmonitor_taskhandlers.go index a32e23fd..e6c38005 100644 --- a/controllers/v1beta2/podmonitor_taskhandlers.go +++ b/internal/controllers/v1beta2/podmonitor_taskhandlers.go @@ -13,7 +13,7 @@ import ( "github.com/go-logr/logr" "github.com/prometheus/client_golang/prometheus" "github.com/uselagoon/machinery/api/schema" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/metrics" corev1 "k8s.io/api/core/v1" diff --git a/controllers/v1beta2/predicates.go b/internal/controllers/v1beta2/predicates.go similarity index 100% rename from controllers/v1beta2/predicates.go rename to internal/controllers/v1beta2/predicates.go diff --git a/controllers/v1beta2/suite_test.go b/internal/controllers/v1beta2/suite_test.go similarity index 92% rename from controllers/v1beta2/suite_test.go rename to internal/controllers/v1beta2/suite_test.go index 6d04f49a..fef428f4 100644 --- a/controllers/v1beta2/suite_test.go +++ b/internal/controllers/v1beta2/suite_test.go @@ -22,7 +22,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" @@ -50,7 +50,7 @@ var _ = BeforeSuite(func(done Done) { By("bootstrapping test environment") testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, } var err error diff --git a/controllers/v1beta2/task_controller.go b/internal/controllers/v1beta2/task_controller.go similarity index 99% rename from controllers/v1beta2/task_controller.go rename to internal/controllers/v1beta2/task_controller.go index cd138fff..bfe64a9b 100644 --- a/controllers/v1beta2/task_controller.go +++ b/internal/controllers/v1beta2/task_controller.go @@ -32,7 +32,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - lagooncrd "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagooncrd "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" "github.com/uselagoon/remote-controller/internal/metrics" ) diff --git a/controllers/v1beta2/task_helpers.go b/internal/controllers/v1beta2/task_helpers.go similarity index 100% rename from controllers/v1beta2/task_helpers.go rename to internal/controllers/v1beta2/task_helpers.go diff --git a/internal/harbor/harbor_credentialrotation.go b/internal/harbor/harbor_credentialrotation.go index 5c6b9ef1..bad6a37a 100644 --- a/internal/harbor/harbor_credentialrotation.go +++ b/internal/harbor/harbor_credentialrotation.go @@ -6,8 +6,8 @@ import ( "context" "time" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" - lagoonv1beta2 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" + lagoonv1beta2 "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" corev1 "k8s.io/api/core/v1" diff --git a/internal/messenger/consumer.go b/internal/messenger/consumer.go index 1129b061..7a3e0b02 100644 --- a/internal/messenger/consumer.go +++ b/internal/messenger/consumer.go @@ -10,8 +10,8 @@ import ( "github.com/cheshir/go-mq/v2" "github.com/uselagoon/machinery/api/schema" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" - lagoonv1beta2 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" + lagoonv1beta2 "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" "gopkg.in/matryer/try.v1" corev1 "k8s.io/api/core/v1" diff --git a/internal/messenger/tasks_handler.go b/internal/messenger/tasks_handler.go index e0554b27..d4da44f6 100644 --- a/internal/messenger/tasks_handler.go +++ b/internal/messenger/tasks_handler.go @@ -6,7 +6,7 @@ import ( "encoding/json" "fmt" - lagoonv1beta2 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagoonv1beta2 "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" diff --git a/internal/messenger/tasks_restore.go b/internal/messenger/tasks_restore.go index a380c4a1..ad481984 100644 --- a/internal/messenger/tasks_restore.go +++ b/internal/messenger/tasks_restore.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/go-logr/logr" - lagoonv1beta2 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagoonv1beta2 "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/helpers" ctrl "sigs.k8s.io/controller-runtime" diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index f87e87e0..f4c8c418 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -1,89 +1,85 @@ package metrics import ( - "fmt" - "net/http" - "time" - - "github.com/go-logr/logr" "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - "github.com/prometheus/client_golang/prometheus/promhttp" + "sigs.k8s.io/controller-runtime/pkg/metrics" ) -// NewServer returns a *http.Server serving prometheus metrics in a new -// goroutine. -// Caller should defer Shutdown() for cleanup. -func NewServer(log logr.Logger, addr string) *http.Server { - mux := http.NewServeMux() - mux.Handle("/metrics", promhttp.Handler()) - s := http.Server{ - Addr: addr, - Handler: mux, - ReadTimeout: 16 * time.Second, - WriteTimeout: 16 * time.Second, - } - go func() { - if err := s.ListenAndServe(); err != http.ErrServerClosed { - log.Error(fmt.Errorf("metrics server did not shut down cleanly"), err.Error()) - } - }() - return &s -} - var ( // general counters for builds - BuildsRunningGauge = promauto.NewGauge(prometheus.GaugeOpts{ - Name: "lagoon_builds_running_current", - Help: "The total number of Lagoon builds running", - }) - BuildsPendingGauge = promauto.NewGauge(prometheus.GaugeOpts{ - Name: "lagoon_builds_pending_current", - Help: "The total number of Lagoon builds pending or queued", - }) - BuildsStartedCounter = promauto.NewCounter(prometheus.CounterOpts{ - Name: "lagoon_builds_started_total", - Help: "The total number of Lagoon builds started", - }) - BuildsCompletedCounter = promauto.NewCounter(prometheus.CounterOpts{ - Name: "lagoon_builds_completed_total", - Help: "The total number of Lagoon builds completed", - }) - BuildsFailedCounter = promauto.NewCounter(prometheus.CounterOpts{ - Name: "lagoon_builds_failed_total", - Help: "The total number of Lagoon builds failed", - }) - BuildsCancelledCounter = promauto.NewCounter(prometheus.CounterOpts{ - Name: "lagoon_builds_cancelled_total", - Help: "The total number of Lagoon builds cancelled", - }) + BuildsRunningGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "lagoon_builds_running_current", + Help: "The total number of Lagoon builds running", + }, + ) + BuildsPendingGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "lagoon_builds_pending_current", + Help: "The total number of Lagoon builds pending or queued", + }, + ) + BuildsStartedCounter = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "lagoon_builds_started_total", + Help: "The total number of Lagoon builds started", + }, + ) + BuildsCompletedCounter = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "lagoon_builds_completed_total", + Help: "The total number of Lagoon builds completed", + }, + ) + BuildsFailedCounter = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "lagoon_builds_failed_total", + Help: "The total number of Lagoon builds failed", + }, + ) + BuildsCancelledCounter = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "lagoon_builds_cancelled_total", + Help: "The total number of Lagoon builds cancelled", + }, + ) // general counters for tasks - TasksRunningGauge = promauto.NewGauge(prometheus.GaugeOpts{ - Name: "lagoon_tasks_running_current", - Help: "The total number of Lagoon tasks running", - }) - TasksStartedCounter = promauto.NewCounter(prometheus.CounterOpts{ - Name: "lagoon_tasks_started_total", - Help: "The total number of Lagoon tasks started", - }) - TasksCompletedCounter = promauto.NewCounter(prometheus.CounterOpts{ - Name: "lagoon_tasks_completed_total", - Help: "The total number of Lagoon tasks completed", - }) - TasksFailedCounter = promauto.NewCounter(prometheus.CounterOpts{ - Name: "lagoon_tasks_failed_total", - Help: "The total number of Lagoon tasks failed", - }) - TasksCancelledCounter = promauto.NewCounter(prometheus.CounterOpts{ - Name: "lagoon_tasks_cancelled_total", - Help: "The total number of Lagoon tasks cancelled", - }) + TasksRunningGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "lagoon_tasks_running_current", + Help: "The total number of Lagoon tasks running", + }, + ) + TasksStartedCounter = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "lagoon_tasks_started_total", + Help: "The total number of Lagoon tasks started", + }, + ) + TasksCompletedCounter = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "lagoon_tasks_completed_total", + Help: "The total number of Lagoon tasks completed", + }, + ) + TasksFailedCounter = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "lagoon_tasks_failed_total", + Help: "The total number of Lagoon tasks failed", + }, + ) + TasksCancelledCounter = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "lagoon_tasks_cancelled_total", + Help: "The total number of Lagoon tasks cancelled", + }, + ) // buildStatus will count the build transisiton steps // when the build step changes, the count is removed and the new step metric is created // this is useful to gauge how long particular steps take in a build - BuildStatus = promauto.NewGaugeVec(prometheus.GaugeOpts{ + BuildStatus = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Name: "lagoon_build_status", Help: "The status of running Lagoon builds", }, @@ -97,7 +93,7 @@ var ( // RunningStatus will count when a build or task is running // when the build or task is complete, the count is removed // this is useful to gauge how long a build or task runs for - BuildRunningStatus = promauto.NewGaugeVec(prometheus.GaugeOpts{ + BuildRunningStatus = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Name: "lagoon_build_running_status", Help: "The duration of running Lagoon builds", }, @@ -106,7 +102,7 @@ var ( "build_namespace", }, ) - TaskRunningStatus = promauto.NewGaugeVec(prometheus.GaugeOpts{ + TaskRunningStatus = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Name: "lagoon_task_running_status", Help: "The duration of running Lagoon tasks", }, @@ -116,3 +112,23 @@ var ( }, ) ) + +func init() { + // Register custom metrics with the global prometheus registry + metrics.Registry.MustRegister( + BuildsRunningGauge, + BuildsPendingGauge, + BuildsStartedCounter, + BuildsCompletedCounter, + BuildsFailedCounter, + BuildsCancelledCounter, + TasksRunningGauge, + TasksStartedCounter, + TasksCompletedCounter, + TasksFailedCounter, + TasksCancelledCounter, + BuildStatus, + BuildRunningStatus, + TaskRunningStatus, + ) +} diff --git a/internal/utilities/deletions/process.go b/internal/utilities/deletions/process.go index 3738e18e..8eb5574f 100644 --- a/internal/utilities/deletions/process.go +++ b/internal/utilities/deletions/process.go @@ -9,8 +9,8 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - lagoonv1beta1 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta1" - lagoonv1beta2 "github.com/uselagoon/remote-controller/apis/lagoon/v1beta2" + lagoonv1beta1 "github.com/uselagoon/remote-controller/api/lagoon/v1beta1" + lagoonv1beta2 "github.com/uselagoon/remote-controller/api/lagoon/v1beta2" "github.com/uselagoon/remote-controller/internal/harbor" ) diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index b228eddc..29dae687 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -40,6 +40,20 @@ var ( duration = 600 * time.Second interval = 1 * time.Second + + metricLabels = []string{ + "lagoon_builds_cancelled_total", + "lagoon_builds_completed_total", + "lagoon_builds_failed_total", + "lagoon_builds_pending_current", + "lagoon_builds_running_current", + "lagoon_builds_started_total", + "lagoon_tasks_cancelled_total", + "lagoon_tasks_completed_total", + "lagoon_tasks_failed_total", + "lagoon_tasks_running_current", + "lagoon_tasks_started_total", + } ) func init() { @@ -55,10 +69,21 @@ var _ = Describe("controller", Ordered, func() { By("creating manager namespace") cmd := exec.Command("kubectl", "create", "ns", namespace) _, _ = utils.Run(cmd) + + // when running a re-test, it is best to make sure the old namespace doesn't exist + By("removing existing test resources") + // remove the old namespace + cmd = exec.Command("kubectl", "delete", "ns", "nginx-example-main") + _, _ = utils.Run(cmd) + // clean up the k8up crds + utils.UninstallK8upCRDs() }) // comment to prevent cleaning up controller namespace and local services AfterAll(func() { + By("stop metrics consumer") + utils.StopMetricsConsumer() + By("removing manager namespace") cmd := exec.Command("kubectl", "delete", "ns", namespace) _, _ = utils.Run(cmd) @@ -69,6 +94,7 @@ var _ = Describe("controller", Ordered, func() { Context("Operator", func() { It("should run successfully", func() { + // start tests var controllerPodName string var err error @@ -116,7 +142,6 @@ var _ = Describe("controller", Ordered, func() { controllerPodName = podNames[0] ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager")) - // Validate pod status cmd = exec.Command("kubectl", "get", "pods", controllerPodName, "-o", "jsonpath={.status.phase}", "-n", namespace, @@ -130,6 +155,11 @@ var _ = Describe("controller", Ordered, func() { } EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed()) + By("start metrics consumer") + Expect(utils.StartMetricsConsumer()).To(Succeed()) + + time.Sleep(30 * time.Second) + By("validating that lagoonbuilds are working") for _, name := range []string{"7m5zypx", "8m5zypx", "9m5zypx", "1m5zypx"} { if name == "9m5zypx" { @@ -298,13 +328,7 @@ var _ = Describe("controller", Ordered, func() { } for name, restore := range restores { By(fmt.Sprintf("installing %s crds", name)) - cmd = exec.Command( - "kubectl", - "apply", - "-f", - fmt.Sprintf("test/e2e/testdata/%s-crds.yaml", name), - ) - _, err = utils.Run(cmd) + err := utils.InstallK8upCRD(name) ExpectWithOffset(1, err).NotTo(HaveOccurred()) time.Sleep(5 * time.Second) @@ -363,7 +387,6 @@ var _ = Describe("controller", Ordered, func() { controllerPodName = podNames[0] ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager")) verifyRobotCredentialsRotate := func() error { - // Validate pod status cmd = exec.Command("kubectl", "logs", controllerPodName, "-c", "manager", "-n", namespace, @@ -411,9 +434,20 @@ var _ = Describe("controller", Ordered, func() { return nil } EventuallyWithOffset(1, verifyNamespaceRemoved, duration, interval).Should(Succeed()) + + By("validating that unauthenticated metrics requests fail") + runCmd := `curl -s -k https://remote-controller-controller-manager-metrics-service.remote-controller-system.svc.cluster.local:8443/metrics | grep -v "#" | grep "lagoon_"` + _, err = utils.RunCommonsCommand(namespace, runCmd) + ExpectWithOffset(2, err).To(HaveOccurred()) + + By("validating that authenticated metrics requests succeed with metrics") + runCmd = `curl -s -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://remote-controller-controller-manager-metrics-service.remote-controller-system.svc.cluster.local:8443/metrics | grep -v "#" | grep "lagoon_"` + output, err := utils.RunCommonsCommand(namespace, runCmd) + ExpectWithOffset(2, err).NotTo(HaveOccurred()) + fmt.Printf("metrics: %s", string(output)) + err = utils.CheckStringContainsStrings(string(output), metricLabels) + ExpectWithOffset(2, err).NotTo(HaveOccurred()) + // End tests }) - // uncomment to debug ... - // time.Sleep(5 * time.Minute) }) - }) diff --git a/test/e2e/testdata/k8up-v1-crds.yaml b/test/e2e/testdata/k8up-v1-crds.yaml deleted file mode 100644 index 7cde61d7..00000000 --- a/test/e2e/testdata/k8up-v1-crds.yaml +++ /dev/null @@ -1,540 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: restores.k8up.io -spec: - group: k8up.io - names: - kind: Restore - listKind: RestoreList - plural: restores - singular: restore - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Reference to Schedule - jsonPath: .metadata.ownerReferences[?(@.kind == "Schedule")].name - name: Schedule Ref - type: string - - description: Status of Completion - jsonPath: .status.conditions[?(@.type == "Completed")].reason - name: Completion - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: Restore is the Schema for the restores 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: RestoreSpec can either contain an S3 restore point or a local one. For the local one you need to define an existing PVC. - properties: - backend: - description: Backend contains the restic repo where the job should backup to. - properties: - azure: - properties: - accountKeySecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - accountNameSecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - container: - type: string - type: object - b2: - properties: - accountIDSecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - accountKeySecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - bucket: - type: string - path: - type: string - type: object - envFrom: - description: EnvFrom adds all environment variables from a an external source to the Restic job. - items: - description: EnvFromSource represents the source of a set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - gcs: - properties: - accessTokenSecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - bucket: - type: string - projectIDSecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - local: - properties: - mountPath: - type: string - type: object - repoPasswordSecretRef: - description: RepoPasswordSecretRef references a secret key to look up the restic repository password - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - rest: - properties: - passwordSecretReg: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - url: - type: string - userSecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - s3: - properties: - accessKeyIDSecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - bucket: - type: string - endpoint: - type: string - secretAccessKeySecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - swift: - properties: - container: - type: string - path: - type: string - type: object - type: object - failedJobsHistoryLimit: - description: FailedJobsHistoryLimit amount of failed jobs to keep for later analysis. KeepJobs is used property is not specified. - type: integer - keepJobs: - description: "KeepJobs amount of jobs to keep for later analysis. \n Deprecated: Use FailedJobsHistoryLimit and SuccessfulJobsHistoryLimit respectively." - type: integer - podSecurityContext: - description: PodSecurityContext describes the security context with which this action shall be executed. - properties: - fsGroup: - description: "A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod: \n 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw---- \n If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies to the container. - type: string - role: - description: Role is a SELinux role label that applies to the container. - type: string - type: - description: Type is a SELinux type label that applies to the container. - type: string - user: - description: User is a SELinux user label that applies to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process run in each container, in addition to the container's primary GID. If unspecified, no groups will be added to any container. Note that this field cannot be set when spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported sysctls (by the container runtime) might fail to launch. Note that this field cannot be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to all containers. If unspecified, the options within a container's SecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - resources: - description: Resources describes the compute resource requirements (cpu, memory, etc.) - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - restoreFilter: - type: string - restoreMethod: - description: RestoreMethod contains how and where the restore should happen all the settings are mutual exclusive. - properties: - folder: - properties: - claimName: - description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - type: string - readOnly: - description: readOnly Will force the ReadOnly setting in VolumeMounts. Default false. - type: boolean - required: - - claimName - type: object - s3: - properties: - accessKeyIDSecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - bucket: - type: string - endpoint: - type: string - secretAccessKeySecretRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - type: object - snapshot: - type: string - successfulJobsHistoryLimit: - description: SuccessfulJobsHistoryLimit amount of successful jobs to keep for later analysis. KeepJobs is used property is not specified. - type: integer - tags: - description: Tags is a list of arbitrary tags that get added to the backup via Restic's tagging system - items: - type: string - type: array - type: object - status: - description: Status defines the observed state of a generic K8up job. It is used for the operator to determine what to do. - properties: - conditions: - description: Conditions provide a standard mechanism for higher-level status reporting from a controller. They are an extension mechanism which allows tools and other controllers to collect summary information about resources without needing to understand resource-specific status details. - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - exclusive: - type: boolean - finished: - type: boolean - started: - type: boolean - type: object - type: object - served: true - storage: true - subresources: - status: {} \ No newline at end of file diff --git a/test/e2e/testdata/k8up-v1alpha1-crds.yaml b/test/e2e/testdata/k8up-v1alpha1-crds.yaml deleted file mode 100644 index 640e1032..00000000 --- a/test/e2e/testdata/k8up-v1alpha1-crds.yaml +++ /dev/null @@ -1,605 +0,0 @@ -kind: CustomResourceDefinition -apiVersion: apiextensions.k8s.io/v1 -metadata: - name: restores.backup.appuio.ch - annotations: - controller-gen.kubebuilder.io/version: v0.5.0 -spec: - group: backup.appuio.ch - names: - plural: restores - singular: restore - kind: Restore - listKind: RestoreList - scope: Namespaced - versions: - - name: v1alpha1 - served: true - storage: true - schema: - openAPIV3Schema: - description: Restore is the Schema for the restores API - type: object - 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: >- - RestoreSpec can either contain an S3 restore point or a local - one. For the local one you need to define an existing PVC. - type: object - properties: - backend: - description: >- - Backend contains the restic repo where the job should backup - to. - type: object - properties: - azure: - type: object - properties: - accountKeySecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - accountNameSecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - container: - type: string - b2: - type: object - properties: - accountIDSecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - accountKeySecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - bucket: - type: string - path: - type: string - gcs: - type: object - properties: - accessTokenSecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - bucket: - type: string - projectIDSecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - local: - type: object - properties: - mountPath: - type: string - repoPasswordSecretRef: - description: >- - RepoPasswordSecretRef references a secret key to look up - the restic repository password - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - rest: - type: object - properties: - passwordSecretReg: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - url: - type: string - userSecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - s3: - type: object - properties: - accessKeyIDSecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - bucket: - type: string - endpoint: - type: string - secretAccessKeySecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - swift: - type: object - properties: - container: - type: string - path: - type: string - failedJobsHistoryLimit: - description: >- - FailedJobsHistoryLimit amount of failed jobs to keep for - later analysis. KeepJobs is used property is not specified. - type: integer - keepJobs: - description: |- - KeepJobs amount of jobs to keep for later analysis. - Deprecated: Use FailedJobsHistoryLimit and SuccessfulJobsHistoryLimit respectively. - type: integer - resources: - description: >- - Resources describes the compute resource requirements (cpu, - memory, etc.) - type: object - properties: - limits: - description: >- - Limits describes the maximum amount of compute resources - allowed. More info: - https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ - type: object - additionalProperties: - pattern: >- - ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - requests: - description: >- - Requests describes the minimum amount of compute - resources required. If Requests is omitted for a - container, it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined value. - More info: - https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ - type: object - additionalProperties: - pattern: >- - ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - restoreFilter: - type: string - restoreMethod: - description: >- - RestoreMethod contains how and where the restore should - happen all the settings are mutual exclusive. - type: object - properties: - folder: - type: object - required: - - claimName - properties: - claimName: - description: >- - ClaimName is the name of a PersistentVolumeClaim in - the same namespace as the pod using this volume. - More info: - https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims - type: string - readOnly: - description: >- - Will force the ReadOnly setting in VolumeMounts. - Default false. - type: boolean - s3: - type: object - properties: - accessKeyIDSecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - bucket: - type: string - endpoint: - type: string - secretAccessKeySecretRef: - description: SecretKeySelector selects a key of a Secret. - type: object - required: - - key - properties: - key: - description: >- - The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: >- - Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid? - type: string - optional: - description: >- - Specify whether the Secret or its key must be - defined - type: boolean - snapshot: - type: string - successfulJobsHistoryLimit: - description: >- - SuccessfulJobsHistoryLimit amount of successful jobs to keep - for later analysis. KeepJobs is used property is not - specified. - type: integer - tags: - description: >- - Tags is a list of arbitrary tags that get added to the - backup via Restic's tagging system - type: array - items: - type: string - status: - description: >- - Status defines the observed state of a generic K8up job. It is - used for the operator to determine what to do. - type: object - properties: - conditions: - description: >- - Conditions provide a standard mechanism for higher-level - status reporting from a controller. They are an extension - mechanism which allows tools and other controllers to - collect summary information about resources without needing - to understand resource-specific status details. - type: array - items: - description: >- - Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended - for direct use as an array at the field path - .status.conditions. For example, type FooStatus - struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: - "Available", "Progressing", and "Degraded" // - +patchMergeKey=type // +patchStrategy=merge // - +listType=map // +listMapKey=type Conditions - []metav1.Condition `json:"conditions,omitempty" - patchStrategy:"merge" patchMergeKey:"type" - protobuf:"bytes,1,rep,name=conditions"` - // other fields } - type: object - required: - - lastTransitionTime - - message - - reason - - status - - type - properties: - lastTransitionTime: - description: >- - lastTransitionTime is the last time the condition - transitioned from one status to another. This should - be when the underlying condition changed. If that is - not known, then using the time when the API field - changed is acceptable. - type: string - format: date-time - message: - description: >- - message is a human readable message indicating details - about the transition. This may be an empty string. - type: string - maxLength: 32768 - observedGeneration: - description: >- - observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, - if .metadata.generation is currently 12, but the - .status.conditions[x].observedGeneration is 9, the - condition is out of date with respect to the current - state of the instance. - type: integer - format: int64 - minimum: 0 - reason: - description: >- - reason contains a programmatic identifier indicating - the reason for the condition's last transition. - Producers of specific condition types may define - expected values and meanings for this field, and - whether the values are considered a guaranteed API. - The value should be a CamelCase string. This field may - not be empty. - type: string - maxLength: 1024 - minLength: 1 - pattern: '^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$' - status: - description: 'status of the condition, one of True, False, Unknown.' - type: string - enum: - - 'True' - - 'False' - - Unknown - type: - description: >- - type of condition in CamelCase or in - foo.example.com/CamelCase. --- Many .condition.type - values are consistent across resources like Available, - but because arbitrary conditions can be useful (see - .node.status.conditions), the ability to deconflict is - important. The regex it matches is - (dns1123SubdomainFmt/)?(qualifiedNameFmt) - type: string - maxLength: 316 - pattern: >- - ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - exclusive: - type: boolean - finished: - type: boolean - started: - type: boolean - subresources: - status: {} - additionalPrinterColumns: - - name: Schedule Ref - type: string - description: Reference to Schedule - jsonPath: '.metadata.ownerReferences[?(@.kind == "Schedule")].name' - - name: Completion - type: string - description: Status of Completion - jsonPath: '.status.conditions[?(@.type == "Completed")].reason' - - name: Age - type: date - jsonPath: .metadata.creationTimestamp - conversion: - strategy: None \ No newline at end of file diff --git a/test/e2e/testdata/metrics-consumer.yaml b/test/e2e/testdata/metrics-consumer.yaml new file mode 100644 index 00000000..97969413 --- /dev/null +++ b/test/e2e/testdata/metrics-consumer.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: metrics-consumer + namespace: remote-controller-system + labels: + app: metrics-consumer +spec: + serviceAccountName: remote-controller-controller-manager + containers: + - name: metrics-consumer + image: uselagoon/commons:latest + command: ["/bin/sh"] + args: ["-c", "sleep 3000"] diff --git a/test/utils/utils.go b/test/utils/utils.go index 9a7a7a33..92e885ef 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -22,11 +22,16 @@ import ( "os/exec" "strings" - . "github.com/onsi/ginkgo/v2" //nolint:golint,revive + "github.com/onsi/ginkgo/v2" +) + +const ( + k8upv1alpha1crd = "https://github.com/k8up-io/k8up/releases/download/v1.2.0/k8up-crd.yaml" + k8upv1crd = "https://github.com/k8up-io/k8up/releases/download/k8up-4.8.0/k8up-crd.yaml" ) func warnError(err error) { - fmt.Fprintf(GinkgoWriter, "warning: %v\n", err) + fmt.Fprintf(ginkgo.GinkgoWriter, "warning: %v\n", err) } // StartLocalServices starts local services @@ -51,18 +56,55 @@ func InstallBulkStorage() error { return err } +func StartMetricsConsumer() error { + cmd := exec.Command("kubectl", "apply", "-f", "test/e2e/testdata/metrics-consumer.yaml") + _, err := Run(cmd) + return err +} + +func StopMetricsConsumer() { + cmd := exec.Command("kubectl", "delete", "-f", "test/e2e/testdata/metrics-consumer.yaml") + if _, err := Run(cmd); err != nil { + warnError(err) + } +} + +// Installs a CRD file but doesn't cause a failure if it already exists +func InstallK8upCRD(version string) error { + crd := k8upv1alpha1crd + if version == "k8up-v1" { + crd = k8upv1crd + } + cmd := exec.Command("kubectl", "create", "-f", crd) + _, err := Run(cmd) + return err +} + +// Removes a CRD file but doesn't cause a failure if already deleted +func UninstallK8upCRDs() { + cmd := exec.Command("kubectl", "delete", "-f", k8upv1alpha1crd) + _, _ = Run(cmd) + cmd = exec.Command("kubectl", "delete", "-f", k8upv1crd) + _, _ = Run(cmd) +} + +func RunCommonsCommand(ns, runCmd string) ([]byte, error) { + cmd := exec.Command("kubectl", "-n", ns, "exec", "metrics-consumer", "--", "sh", "-c", runCmd) + return Run(cmd) +} + // Run executes the provided command within this context func Run(cmd *exec.Cmd) ([]byte, error) { dir, _ := GetProjectDir() cmd.Dir = dir if err := os.Chdir(cmd.Dir); err != nil { - fmt.Fprintf(GinkgoWriter, "chdir dir: %s\n", err) + fmt.Fprintf(ginkgo.GinkgoWriter, "chdir dir: %s\n", err) } cmd.Env = append(os.Environ(), "GO111MODULE=on") command := strings.Join(cmd.Args, " ") - fmt.Fprintf(GinkgoWriter, "running: %s\n", command) + fmt.Fprintf(ginkgo.GinkgoWriter, "running: %s\n", command) output, err := cmd.CombinedOutput() if err != nil { return output, fmt.Errorf("%s failed with error: (%v) %s", command, err, string(output)) @@ -106,3 +148,12 @@ func GetProjectDir() (string, error) { wd = strings.Replace(wd, "/test/e2e", "", -1) return wd, nil } + +func CheckStringContainsStrings(str string, strs []string) error { + for _, s := range strs { + if !strings.Contains(str, s) { + return fmt.Errorf("string %s not found in strings", s) + } + } + return nil +}