diff --git a/Makefile b/Makefile index 56bb4aba..59245e1e 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,15 @@ CERTS_INIT_IMG ?= quay.io/validator-labs/validator-certs-init:latest # Helm vars CHART_NAME=validator +VALIDATION_RESULTS_CRD = chart/validator/crds/validation.spectrocloud.labs_validationresults.yaml +VALIDATOR_CONFIGS_CRD = chart/validator/crds/validation.spectrocloud.labs_validatorconfigs.yaml + reviewable-ext: @$(INFO) Checking for plugin version updates... bash hack/update-versions.sh + rm $(VALIDATION_RESULTS_CRD) $(VALIDATOR_CONFIGS_CRD) + cp config/crd/bases/validation.spectrocloud.labs_validationresults.yaml $(VALIDATION_RESULTS_CRD) + cp config/crd/bases/validation.spectrocloud.labs_validatorconfigs.yaml $(VALIDATOR_CONFIGS_CRD) .PHONY: docker-build-certs-init docker-build-certs-init: ## Build validator-certs-init docker image. @@ -31,4 +37,4 @@ HAULER_VERSION ?= 1.0.4 .PHONY: hauler hauler: ## Install hauler curl -sfL https://get.hauler.dev | HAULER_VERSION=$(HAULER_VERSION) bash -HAULER = /usr/local/bin/hauler \ No newline at end of file +HAULER = /usr/local/bin/hauler diff --git a/api/v1alpha1/validatorconfig_types.go b/api/v1alpha1/validatorconfig_types.go index 7c7808cb..9eb6277d 100644 --- a/api/v1alpha1/validatorconfig_types.go +++ b/api/v1alpha1/validatorconfig_types.go @@ -23,6 +23,9 @@ import ( // ValidatorConfigSpec defines the desired state of ValidatorConfig. type ValidatorConfigSpec struct { + // HelmConfig defines the configuration for the Helm registry. + HelmConfig HelmConfig `json:"helmConfig" yaml:"helmConfig"` + // Plugins defines the configuration for the validator plugins. Plugins []HelmRelease `json:"plugins,omitempty" yaml:"plugins,omitempty"` @@ -54,11 +57,17 @@ type HelmChart struct { // Name of the Helm chart. Name string `json:"name" yaml:"name"` - // Repository URL of the Helm chart. + // Repository of the Helm chart. Repository string `json:"repository" yaml:"repository"` // Version of the Helm chart. Version string `json:"version" yaml:"version"` +} + +// HelmConfig defines the configuration for the Helm registry. +type HelmConfig struct { + // Registry is the URL of the Helm registry. + Registry string `json:"registry" yaml:"registry"` // CAFile is the path to the CA certificate for the Helm repository. CAFile string `json:"caFile,omitempty" yaml:"caFile,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 3132678a..66aa66c7 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -40,6 +40,21 @@ func (in *HelmChart) DeepCopy() *HelmChart { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HelmConfig) DeepCopyInto(out *HelmConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmConfig. +func (in *HelmConfig) DeepCopy() *HelmConfig { + if in == nil { + return nil + } + out := new(HelmConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HelmRelease) DeepCopyInto(out *HelmRelease) { *out = *in @@ -262,6 +277,7 @@ func (in *ValidatorConfigList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ValidatorConfigSpec) DeepCopyInto(out *ValidatorConfigSpec) { *out = *in + out.HelmConfig = in.HelmConfig if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make([]HelmRelease, len(*in)) diff --git a/chart/validator/README.md b/chart/validator/README.md index 5b45c83f..c05273fd 100644 --- a/chart/validator/README.md +++ b/chart/validator/README.md @@ -51,7 +51,8 @@ The following table lists the configurable parameters of the Validator chart and | `pluginSecrets.vSphere` | Don't forget to delete these curly braces if you're specifying credentials here! | `{}` | | `pluginSecrets.oci.auth` | Don't forget to delete these square brackets if you're specifying credentials here! | `[]` | | `pluginSecrets.oci.pubKeys` | Don't forget to delete these square brackets if you're specifying public keys here! | `[]` | -| `plugins` | | `[{"chart": {"name": "validator-plugin-azure", "repository": "https://validator-labs.github.io/validator-plugin-azure", "version": "v0.0.14"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-azure\n tag: v0.0.14\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n # Optionally specify a volumeMount to mount a volume containing a private key\n # to leverage Azure Service principal with certificate authentication.\n volumeMounts: []\n replicas: 1\n serviceAccount:\n annotations: {}\n # Optionally specify a volume containing a private key to leverage Azure Service\n # principal with certificate authentication.\n volumes: []\n # Optionally specify additional labels to use for the controller-manager Pods.\n podLabels: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP\nauth:\n # Leave secret undefined for implicit auth (e.g., WorkloadIdentity credentials)\n secret: {}\n # Specify the name of a secret in your cluster that contains Azure credentials.\n # E.g.: https://github.com/validator-labs/validator/blob/main/chart/validator/templates/plugin-secret-azure.yaml\n # secretName: azure-creds\n\n # Override the service account used by Azure validator (optional, could be used for WorkloadIdentityCredentials on AKS)\n # WARNING: the chosen service account must include all RBAC privileges found in templates/manager-rbac.yaml\n serviceAccountName: \"\""}, {"chart": {"name": "validator-plugin-oci", "repository": "https://validator-labs.github.io/validator-plugin-oci", "version": "v0.0.12"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-oci\n tag: v0.0.12\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP"}, {"chart": {"name": "validator-plugin-kubescape", "repository": "https://validator-labs.github.io/validator-plugin-kubescape", "version": "v0.0.4"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-kubescape\n tag: v0.0.4\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n # Optionally specify a volumeMount to mount a volume containing a private key\n # to leverage Azure Service principal with certificate authentication.\n volumeMounts: []\n replicas: 1\n serviceAccount:\n annotations: {}\n # Optionally specify a volume containing a private key to leverage Azure Service\n # principal with certificate authentication.\n volumes: []\n # Optionally specify additional labels to use for the controller-manager Pods.\n podLabels: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP"}, {"chart": {"name": "validator-plugin-aws", "repository": "https://validator-labs.github.io/validator-plugin-aws", "version": "v0.1.2"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-aws\n tag: v0.1.2\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP\nauth:\n # Leave secret undefined for implicit auth (node instance IAM role, IAM roles for Service Accounts, etc.)\n secret: {}\n # Specify the name of a secret in your cluster that contains AWS credentials.\n # E.g.: https://github.com/validator-labs/validator/blob/main/chart/validator/templates/plugin-secret-aws.yaml\n # secretName: aws-creds\n\n # Override the service account used by AWS validator (optional, could be used for IAM roles for Service Accounts)\n # WARNING: the chosen service account must have the same RBAC privileges as seen in templates/manager-rbac.yaml\n serviceAccountName: \"\""}, {"chart": {"name": "validator-plugin-network", "repository": "https://validator-labs.github.io/validator-plugin-network", "version": "v0.0.20"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: true\n capabilities:\n add:\n - NET_RAW\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-network\n tag: v0.0.20\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP"}, {"chart": {"name": "validator-plugin-maas", "repository": "https://validator-labs.github.io/validator-plugin-maas", "version": "v0.0.5"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-maas\n tag: v0.0.5\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP"}, {"chart": {"name": "validator-plugin-vsphere", "repository": "https://validator-labs.github.io/validator-plugin-vsphere", "version": "v0.0.28"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --metrics-bind-address=127.0.0.1:8080\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-vsphere\n tag: v0.0.28\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP\nauth:\n # Specify the name of a secret in your cluster that contains vSphere credentials.\n # E.g.: https://github.com/validator-labs/validator/blob/main/chart/validator/templates/plugin-secret-vsphere.yaml\n secretName: vsphere-credentials"}]` | +| `helmConfig.registry` | | `"https://validator-labs.github.io"` | +| `plugins` | | `[{"chart": {"name": "validator-plugin-azure", "repository": "validator-plugin-azure", "version": "v0.0.14"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-azure\n tag: v0.0.14\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n # Optionally specify a volumeMount to mount a volume containing a private key\n # to leverage Azure Service principal with certificate authentication.\n volumeMounts: []\n replicas: 1\n serviceAccount:\n annotations: {}\n # Optionally specify a volume containing a private key to leverage Azure Service\n # principal with certificate authentication.\n volumes: []\n # Optionally specify additional labels to use for the controller-manager Pods.\n podLabels: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP\nauth:\n # Leave secret undefined for implicit auth (e.g., WorkloadIdentity credentials)\n secret: {}\n # Specify the name of a secret in your cluster that contains Azure credentials.\n # E.g.: https://github.com/validator-labs/validator/blob/main/chart/validator/templates/plugin-secret-azure.yaml\n # secretName: azure-creds\n\n # Override the service account used by Azure validator (optional, could be used for WorkloadIdentityCredentials on AKS)\n # WARNING: the chosen service account must include all RBAC privileges found in templates/manager-rbac.yaml\n serviceAccountName: \"\""}, {"chart": {"name": "validator-plugin-oci", "repository": "validator-plugin-oci", "version": "v0.0.12"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-oci\n tag: v0.0.12\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP"}, {"chart": {"name": "validator-plugin-kubescape", "repository": "validator-plugin-kubescape", "version": "v0.0.4"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-kubescape\n tag: v0.0.4\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n # Optionally specify a volumeMount to mount a volume containing a private key\n # to leverage Azure Service principal with certificate authentication.\n volumeMounts: []\n replicas: 1\n serviceAccount:\n annotations: {}\n # Optionally specify a volume containing a private key to leverage Azure Service\n # principal with certificate authentication.\n volumes: []\n # Optionally specify additional labels to use for the controller-manager Pods.\n podLabels: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP"}, {"chart": {"name": "validator-plugin-aws", "repository": "validator-plugin-aws", "version": "v0.1.2"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-aws\n tag: v0.1.2\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP\nauth:\n # Leave secret undefined for implicit auth (node instance IAM role, IAM roles for Service Accounts, etc.)\n secret: {}\n # Specify the name of a secret in your cluster that contains AWS credentials.\n # E.g.: https://github.com/validator-labs/validator/blob/main/chart/validator/templates/plugin-secret-aws.yaml\n # secretName: aws-creds\n\n # Override the service account used by AWS validator (optional, could be used for IAM roles for Service Accounts)\n # WARNING: the chosen service account must have the same RBAC privileges as seen in templates/manager-rbac.yaml\n serviceAccountName: \"\""}, {"chart": {"name": "validator-plugin-network", "repository": "validator-plugin-network", "version": "v0.0.20"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: true\n capabilities:\n add:\n - NET_RAW\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-network\n tag: v0.0.20\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP"}, {"chart": {"name": "validator-plugin-maas", "repository": "validator-plugin-maas", "version": "v0.0.5"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-maas\n tag: v0.0.5\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP"}, {"chart": {"name": "validator-plugin-vsphere", "repository": "validator-plugin-vsphere", "version": "v0.0.28"}, "values": "controllerManager:\n kubeRbacProxy:\n args:\n - --secure-listen-address=0.0.0.0:8443\n - --upstream=http://127.0.0.1:8080/\n - --logtostderr=true\n - --v=0\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: gcr.io/kubebuilder/kube-rbac-proxy\n tag: v0.16.0\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 5m\n memory: 64Mi\n manager:\n args:\n - --health-probe-bind-address=:8081\n - --metrics-bind-address=127.0.0.1:8080\n - --leader-elect\n containerSecurityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n image:\n repository: quay.io/validator-labs/validator-plugin-vsphere\n tag: v0.0.28\n resources:\n limits:\n cpu: 500m\n memory: 128Mi\n requests:\n cpu: 10m\n memory: 64Mi\n replicas: 1\n serviceAccount:\n annotations: {}\nkubernetesClusterDomain: cluster.local\nmetricsService:\n ports:\n - name: https\n port: 8443\n protocol: TCP\n targetPort: https\n type: ClusterIP\nauth:\n # Specify the name of a secret in your cluster that contains vSphere credentials.\n # E.g.: https://github.com/validator-labs/validator/blob/main/chart/validator/templates/plugin-secret-vsphere.yaml\n secretName: vsphere-credentials"}]` | diff --git a/chart/validator/crds/validation.spectrocloud.labs_validationresults.yaml b/chart/validator/crds/validation.spectrocloud.labs_validationresults.yaml index bd8d6a32..301d069a 100644 --- a/chart/validator/crds/validation.spectrocloud.labs_validationresults.yaml +++ b/chart/validator/crds/validation.spectrocloud.labs_validationresults.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: validationresults.validation.spectrocloud.labs spec: group: validation.spectrocloud.labs @@ -30,22 +30,27 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: ValidationResult is the Schema for the validationresults API + description: ValidationResult is the Schema for the validationresults 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' + 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' + 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: ValidationResultSpec defines the desired state of ValidationResult + description: ValidationResultSpec defines the desired state of ValidationResult. properties: expectedResults: description: The number of rules in the validator plugin spec, hence @@ -53,51 +58,55 @@ spec: minimum: 1 type: integer plugin: + description: Plugin is the plugin code of the validator plugin that + was executed. type: string required: - expectedResults - plugin type: object status: - description: ValidationResultStatus defines the observed state of ValidationResult + description: ValidationResultStatus defines the observed state of ValidationResult. properties: conditions: + description: Conditions is a list of conditions that describe the + current state of the ValidationResult. items: description: Condition defines an observation of a Cluster API resource operational state. properties: lastTransitionTime: - description: 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. + description: |- + 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: A human readable message indicating details about - the transition. This field may be empty. + description: |- + A human readable message indicating details about the transition. + This field may be empty. type: string reason: - description: The reason for the condition's last transition - in CamelCase. The specific API may choose whether or not this - field is considered a guaranteed API. This field may not be - empty. + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. type: string severity: - description: Severity provides an explicit classification of - Reason code, so the users or machines can immediately understand - the current situation and act accordingly. The Severity field - MUST be set only when Status=False. + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. type: string status: description: Status of the condition, one of 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. + 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. type: string required: - lastTransitionTime @@ -106,9 +115,14 @@ spec: type: object type: array state: + description: State is the overall state of the validation result. type: string validationConditions: + description: ValidationConditions is a list of conditions that describe + the validation rules associated with the ValidationResult. items: + description: ValidationCondition describes the state of a validation + rule. properties: details: description: Human-readable messages indicating additional details diff --git a/chart/validator/crds/validation.spectrocloud.labs_validatorconfigs.yaml b/chart/validator/crds/validation.spectrocloud.labs_validatorconfigs.yaml index 4b048a0b..0b9d91cc 100644 --- a/chart/validator/crds/validation.spectrocloud.labs_validatorconfigs.yaml +++ b/chart/validator/crds/validation.spectrocloud.labs_validatorconfigs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: validatorconfigs.validation.spectrocloud.labs spec: group: validation.spectrocloud.labs @@ -17,39 +17,66 @@ spec: - name: v1alpha1 schema: openAPIV3Schema: - description: ValidatorConfig is the Schema for the validatorconfigs API + description: ValidatorConfig is the Schema for the validatorconfigs 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' + 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' + 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: ValidatorConfigSpec defines the desired state of ValidatorConfig + description: ValidatorConfigSpec defines the desired state of ValidatorConfig. properties: + helmConfig: + description: HelmConfig defines the configuration for the Helm registry. + properties: + authSecretName: + description: AuthSecretName is the name of the K8s secret containing + the authentication details for the Helm repository. + type: string + caFile: + description: CAFile is the path to the CA certificate for the + Helm repository. + type: string + insecureSkipVerify: + description: InsecureSkipTLSVerify skips the verification of the + server's certificate chain and host name. + type: boolean + registry: + description: Registry is the URL of the Helm registry. + type: string + required: + - registry + type: object plugins: + description: Plugins defines the configuration for the validator plugins. items: + description: HelmRelease defines the configuration for a Helm chart + release. properties: chart: + description: Chart defines the Helm chart to be installed. properties: - authSecretName: - type: string - caFile: - type: string - insecureSkipVerify: - type: boolean name: + description: Name of the Helm chart. type: string repository: + description: Repository of the Helm chart. type: string version: + description: Version of the Helm chart. type: string required: - name @@ -57,6 +84,8 @@ spec: - version type: object values: + description: Values defines the values to be passed to the Helm + chart. type: string required: - chart @@ -64,12 +93,14 @@ spec: type: object type: array sink: + description: Sink defines the configuration for the notification sink. properties: secretName: - description: Name of a K8s secret containing configuration details - for the sink + description: SecretName is the name of a K8s secret containing + configuration details for the sink. type: string type: + description: Type of the sink. enum: - alertmanager - slack @@ -78,23 +109,28 @@ spec: - secretName - type type: object + required: + - helmConfig type: object status: description: ValidatorConfigStatus defines the observed state of ValidatorConfig properties: conditions: items: + description: ValidatorPluginCondition describes the state of a Validator + plugin. properties: lastUpdatedTime: - description: 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. + description: |- + 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: A human readable message indicating details about - the transition. This field may be empty. + description: |- + A human readable message indicating details about the transition. + This field may be empty. type: string pluginName: description: Name of the Validator plugin. @@ -103,11 +139,10 @@ spec: description: Status of the condition, one of 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. + 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. type: string required: - lastUpdatedTime diff --git a/chart/validator/templates/validator-config.yaml b/chart/validator/templates/validator-config.yaml index 2f9071be..3c2d7d55 100644 --- a/chart/validator/templates/validator-config.yaml +++ b/chart/validator/templates/validator-config.yaml @@ -5,6 +5,11 @@ kind: ValidatorConfig metadata: name: validator-config spec: + helmConfig: + registry: {{ required ".Values.helmConfig.registry is required!" .Values.helmConfig.registry }} + caFile: {{ .Values.helmConfig.caFile }} + insecureSkipVerify: {{ .Values.helmConfig.insecureSkipVerify }} + authSecretName: {{ .Values.helmConfig.authSecretName }} plugins: {{- range .Values.plugins }} - @@ -22,4 +27,4 @@ spec: sink: type: {{ required ".Values.sink.type is required!" .Values.sink.type }} secretName: {{ required ".Values.sink.secretName is required!" .Values.sink.secretName }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/chart/validator/values.yaml b/chart/validator/values.yaml index dfe301cb..4ce3ab13 100644 --- a/chart/validator/values.yaml +++ b/chart/validator/values.yaml @@ -185,11 +185,14 @@ pluginSecrets: # # -----END PUBLIC KEY----- +helmConfig: + registry: "https://validator-labs.github.io" + # Validation plugin charts plugins: - chart: name: validator-plugin-azure - repository: "https://validator-labs.github.io/validator-plugin-azure" + repository: validator-plugin-azure version: v0.0.14 values: |- controllerManager: @@ -264,7 +267,7 @@ plugins: serviceAccountName: "" - chart: name: validator-plugin-oci - repository: "https://validator-labs.github.io/validator-plugin-oci" + repository: validator-plugin-oci version: v0.0.12 values: |- controllerManager: @@ -321,7 +324,7 @@ plugins: type: ClusterIP - chart: name: validator-plugin-kubescape - repository: "https://validator-labs.github.io/validator-plugin-kubescape" + repository: validator-plugin-kubescape version: v0.0.4 values: |- controllerManager: @@ -386,7 +389,7 @@ plugins: type: ClusterIP - chart: name: validator-plugin-aws - repository: "https://validator-labs.github.io/validator-plugin-aws" + repository: validator-plugin-aws version: v0.1.2 values: |- controllerManager: @@ -453,7 +456,7 @@ plugins: serviceAccountName: "" - chart: name: validator-plugin-network - repository: "https://validator-labs.github.io/validator-plugin-network" + repository: validator-plugin-network version: v0.0.20 values: |- controllerManager: @@ -512,7 +515,7 @@ plugins: type: ClusterIP - chart: name: validator-plugin-maas - repository: "https://validator-labs.github.io/validator-plugin-maas" + repository: validator-plugin-maas version: v0.0.5 values: |- controllerManager: @@ -569,7 +572,7 @@ plugins: type: ClusterIP - chart: name: validator-plugin-vsphere - repository: "https://validator-labs.github.io/validator-plugin-vsphere" + repository: validator-plugin-vsphere version: v0.0.28 values: |- controllerManager: diff --git a/config/crd/bases/validation.spectrocloud.labs_validatorconfigs.yaml b/config/crd/bases/validation.spectrocloud.labs_validatorconfigs.yaml index e1e422f6..0b9d91cc 100644 --- a/config/crd/bases/validation.spectrocloud.labs_validatorconfigs.yaml +++ b/config/crd/bases/validation.spectrocloud.labs_validatorconfigs.yaml @@ -39,6 +39,27 @@ spec: spec: description: ValidatorConfigSpec defines the desired state of ValidatorConfig. properties: + helmConfig: + description: HelmConfig defines the configuration for the Helm registry. + properties: + authSecretName: + description: AuthSecretName is the name of the K8s secret containing + the authentication details for the Helm repository. + type: string + caFile: + description: CAFile is the path to the CA certificate for the + Helm repository. + type: string + insecureSkipVerify: + description: InsecureSkipTLSVerify skips the verification of the + server's certificate chain and host name. + type: boolean + registry: + description: Registry is the URL of the Helm registry. + type: string + required: + - registry + type: object plugins: description: Plugins defines the configuration for the validator plugins. items: @@ -48,23 +69,11 @@ spec: chart: description: Chart defines the Helm chart to be installed. properties: - authSecretName: - description: AuthSecretName is the name of the K8s secret - containing the authentication details for the Helm repository. - type: string - caFile: - description: CAFile is the path to the CA certificate for - the Helm repository. - type: string - insecureSkipVerify: - description: InsecureSkipTLSVerify skips the verification - of the server's certificate chain and host name. - type: boolean name: description: Name of the Helm chart. type: string repository: - description: Repository URL of the Helm chart. + description: Repository of the Helm chart. type: string version: description: Version of the Helm chart. @@ -100,6 +109,8 @@ spec: - secretName - type type: object + required: + - helmConfig type: object status: description: ValidatorConfigStatus defines the observed state of ValidatorConfig diff --git a/hack/chart/values-base.yaml b/hack/chart/values-base.yaml index aadcf767..aed47bd8 100644 --- a/hack/chart/values-base.yaml +++ b/hack/chart/values-base.yaml @@ -185,5 +185,8 @@ pluginSecrets: # # -----END PUBLIC KEY----- +helmConfig: + registry: "https://validator-labs.github.io" + # Validation plugin charts plugins: diff --git a/hack/update-versions.sh b/hack/update-versions.sh index 0da6b714..1cf5706c 100755 --- a/hack/update-versions.sh +++ b/hack/update-versions.sh @@ -27,7 +27,7 @@ function addChartValues { cat <> chart/validator/values.yaml - chart: name: $1 - repository: "https://validator-labs.github.io/$1" + repository: $1 version: v$2 values: |- $indentedValues @@ -65,4 +65,4 @@ versions["oci"]=$OCI_VERSION versions["vsphere"]=$VSPHERE_VERSION updateHaulerManifest -updateValues \ No newline at end of file +updateValues diff --git a/hauler-manifest.yaml b/hauler-manifest.yaml index 435b2a3a..ac33f793 100644 --- a/hauler-manifest.yaml +++ b/hauler-manifest.yaml @@ -57,4 +57,4 @@ metadata: spec: files: - name: validatorctl - path: https://github.com/validator-labs/validatorctl/releases/download/v0.0.5/validator-linux-amd64 \ No newline at end of file + path: https://github.com/validator-labs/validatorctl/releases/download/v0.0.6/validator-linux-amd64 \ No newline at end of file diff --git a/internal/controller/testdata/vc-network.yaml b/internal/controller/testdata/vc-network.yaml index f112ecff..9af08059 100644 --- a/internal/controller/testdata/vc-network.yaml +++ b/internal/controller/testdata/vc-network.yaml @@ -9,11 +9,13 @@ metadata: name: validator-config-test namespace: validator spec: + helmConfig: + registry: https://validator-labs.github.io + authSecretName: validator-plugin-network-chart-secret plugins: - chart: name: validator-plugin-network - repository: https://validator-labs.github.io/validator-plugin-network - authSecretName: validator-plugin-network-chart-secret + repository: validator-plugin-network version: v0.0.15 values: |- controllerManager: diff --git a/internal/controller/validatorconfig_controller.go b/internal/controller/validatorconfig_controller.go index 2cc1a4a1..e9ee8d94 100644 --- a/internal/controller/validatorconfig_controller.go +++ b/internal/controller/validatorconfig_controller.go @@ -150,6 +150,7 @@ func (r *ValidatorConfigReconciler) redeployIfNeeded(ctx context.Context, vc *v1 specPlugins := make(map[string]bool) conditions := make([]v1alpha1.ValidatorPluginCondition, len(vc.Spec.Plugins)) + helmConfig := vc.Spec.HelmConfig for i, p := range vc.Spec.Plugins { specPlugins[p.Chart.Name] = true @@ -167,13 +168,14 @@ func (r *ValidatorConfigReconciler) redeployIfNeeded(ctx context.Context, vc *v1 opts := &helm.Options{ Chart: p.Chart.Name, Repo: p.Chart.Repository, + Registry: helmConfig.Registry, Version: p.Chart.Version, Values: p.Values, - InsecureSkipTLSVerify: p.Chart.InsecureSkipTLSVerify, + InsecureSkipTLSVerify: helmConfig.InsecureSkipTLSVerify, } - if p.Chart.AuthSecretName != "" { - nn := types.NamespacedName{Name: p.Chart.AuthSecretName, Namespace: vc.Namespace} + if helmConfig.AuthSecretName != "" { + nn := types.NamespacedName{Name: helmConfig.AuthSecretName, Namespace: vc.Namespace} if err := r.configureHelmOpts(ctx, nn, opts); err != nil { r.Log.V(0).Error(err, "failed to configure basic auth for Helm upgrade") conditions[i] = r.buildHelmChartCondition(p.Chart.Name, err) @@ -182,7 +184,7 @@ func (r *ValidatorConfigReconciler) redeployIfNeeded(ctx context.Context, vc *v1 } var cleanupLocalChart bool - if strings.HasPrefix(p.Chart.Repository, oci.Scheme) { + if strings.HasPrefix(helmConfig.Registry, oci.Scheme) { r.Log.V(0).Info("Pulling plugin Helm chart", "name", p.Chart.Name) opts.Path = fmt.Sprintf("/charts/%s", opts.Chart) @@ -200,7 +202,7 @@ func (r *ValidatorConfigReconciler) redeployIfNeeded(ctx context.Context, vc *v1 continue } ociOpts := oci.ImageOptions{ - Ref: fmt.Sprintf("%s/%s:%s", strings.TrimPrefix(opts.Repo, oci.Scheme), opts.Chart, opts.Version), + Ref: fmt.Sprintf("%s/%s/%s:%s", strings.TrimPrefix(opts.Registry, oci.Scheme), opts.Repo, opts.Chart, opts.Version), OutDir: opts.Path, OutFile: opts.Chart, } diff --git a/internal/controller/validatorconfig_controller_test.go b/internal/controller/validatorconfig_controller_test.go index 8b8388ec..b768a487 100644 --- a/internal/controller/validatorconfig_controller_test.go +++ b/internal/controller/validatorconfig_controller_test.go @@ -147,12 +147,15 @@ var _ = Describe("ValidatorConfig controller", Ordered, func() { Namespace: validatorNamespace, }, Spec: v1alpha1.ValidatorConfigSpec{ + HelmConfig: v1alpha1.HelmConfig{ + Registry: "foo", + AuthSecretName: "chart-secret", + }, Plugins: []v1alpha1.HelmRelease{ { Chart: v1alpha1.HelmChart{ - Name: "foo", - Repository: "bar", - AuthSecretName: "chart-secret", + Repository: "bar", + Name: "bar", }, }, }, @@ -167,7 +170,7 @@ var _ = Describe("ValidatorConfig controller", Ordered, func() { if err := k8sClient.Get(ctx, vcKey, vc); err != nil { return false } - condition, ok := isConditionTrue(vc, "foo", v1alpha1.HelmChartDeployedCondition) + condition, ok := isConditionTrue(vc, "bar", v1alpha1.HelmChartDeployedCondition) return condition.Status == corev1.ConditionFalse && !ok }, timeout, interval).Should(BeTrue(), "failed to deploy validator-plugin-network") }) diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go index e866bdc0..6346b649 100644 --- a/pkg/helm/helm.go +++ b/pkg/helm/helm.go @@ -108,6 +108,9 @@ func (c *CLIClient) run(name, namespace string, options Options, command string, args = append(args, options.Path) } else if options.Chart != "" { args = append(args, options.Chart) + if options.Registry == "" { + return fmt.Errorf("chart registry cannot be null") + } if options.Repo == "" { return fmt.Errorf("chart repo cannot be null") } diff --git a/pkg/helm/options.go b/pkg/helm/options.go index e294c3b8..7b146cd0 100644 --- a/pkg/helm/options.go +++ b/pkg/helm/options.go @@ -1,10 +1,13 @@ package helm +import "fmt" + // Options holds all the options for installing/pulling/upgrading a chart. type Options struct { Chart string Path string + Registry string Repo string Version string Values string @@ -29,7 +32,7 @@ type Options struct { // ConfigureRepo adds the repo flag to the command. func (o Options) ConfigureRepo(args []string) []string { - args = append(args, "--repo", o.Repo) + args = append(args, "--repo", fmt.Sprintf("%s/%s", o.Registry, o.Repo)) return args }