diff --git a/.github/scripts/changelog.sh b/.github/scripts/changelog.sh index 0d363fb..7208aec 100755 --- a/.github/scripts/changelog.sh +++ b/.github/scripts/changelog.sh @@ -3,7 +3,7 @@ set -eu CHART_DIR="charts/cert-manager-webhook-ovh" -CONFIG_VERSION="0.0.1" +CONFIG_VERSION="0.0.2" COMMITS_TO_PUSH="$(git log --oneline -- "origin..HEAD" | awk 'END { print NR }')" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9819b3a..11ccec3 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -56,7 +56,7 @@ jobs: with: context: . push: true - platforms: linux/arm64,linux/arm/v7,linux/amd64 + platforms: linux/amd64 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/charts/cert-manager-webhook-ovh/Chart.yaml b/charts/cert-manager-webhook-ovh/Chart.yaml index 278cef5..c0c880b 100644 --- a/charts/cert-manager-webhook-ovh/Chart.yaml +++ b/charts/cert-manager-webhook-ovh/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -appVersion: "0.7.0" +appVersion: "0.8.0-alpha.1" deprecated: false description: OVH DNS cert-manager ACME webhook home: https://github.com/aureq/cert-manager-webhook-ovh @@ -19,4 +19,4 @@ maintainers: name: cert-manager-webhook-ovh sources: - https://github.com/aureq/cert-manager-webhook-ovh -version: "0.7.0" \ No newline at end of file +version: "0.8.0-alpha.1" \ No newline at end of file diff --git a/charts/cert-manager-webhook-ovh/templates/_helpers.tpl b/charts/cert-manager-webhook-ovh/templates/_helpers.tpl index 33b3b85..33fd83e 100644 --- a/charts/cert-manager-webhook-ovh/templates/_helpers.tpl +++ b/charts/cert-manager-webhook-ovh/templates/_helpers.tpl @@ -52,9 +52,21 @@ Returns true if ovhAuthentication is correctly set. */}} {{- define "cert-manager-webhook-ovh.isOvhAuthenticationAvail" -}} {{- if . -}} - {{- if and (.consumerKey) (.applicationKey) (.applicationSecret) -}} - {{- eq "true" "true" -}} - {{- end -}} + {{- if eq "application" .authenticationMethod }} + {{- if and .applicationConsumerKey .applicationKey .applicationSecret }} + {{- true -}} + {{- else }} + {{- fail "Error: 'applicationConsumerKey', 'applicationKey', and 'applicationSecret' must all be provided for 'application' authentication method." }} + {{- end }} + {{- else if eq "oauth2" .authenticationMethod }} + {{- if and .oauth2ClientId .oauth2ClientSecret }} + {{- true -}} + {{- else }} + {{- fail "Error: 'oauth2ClientId' and 'oauth2ClientSecret' must both be provided for 'oauth2' authentication method." }} + {{- end }} + {{- else }} + {{- fail "Error: Invalid 'authenticationMethod'. It must be either 'application' or 'oauth2'." }} + {{- end }} {{- end -}} {{- end -}} @@ -63,19 +75,37 @@ Returns true if ovhAuthenticationRef is correctly set. */}} {{- define "cert-manager-webhook-ovh.isOvhAuthenticationRefAvail" -}} {{- if . -}} - {{- if or (not .consumerKeyRef) (not .applicationKeyRef) (not .applicationSecretRef) }} - {{- fail "Error: When 'ovhAuthenticationRef' is used, 'consumerKeyRef', 'applicationKeyRef' and 'applicationSecretRef' need to be provided." }} - {{- end }} - {{- if or (not .consumerKeyRef.name) (not .consumerKeyRef.key) }} - {{ fail "Error: When 'ovhAuthenticationRef' is used, you need to provide 'ovhAuthenticationRef.consumerKeyRef.name' and 'ovhAuthenticationRef.consumerKeyRef.key'" }} - {{- end }} - {{- if or (not .applicationKeyRef.name) (not .applicationKeyRef.key) }} - {{ fail "Error: When 'ovhAuthenticationRef' is used, you need to provide 'ovhAuthenticationRef.applicationKeyRef.name' and 'ovhAuthenticationRef.applicationKeyRef.key'" }} - {{- end }} - {{- if or (not .applicationSecretRef.name) (not .applicationSecretRef.key) }} - {{ fail "Error: When 'ovhAuthenticationRef' is used, you need to provide 'ovhAuthenticationRef.applicationSecretRef.name' and 'ovhAuthenticationRef.applicationSecretRef.key'" }} + {{- if eq "application" .authenticationMethod }} + {{- if and (not .applicationConsumerKeyRef) (not .applicationKeyRef) (not .applicationSecretRef) }} + {{- fail "Error: When 'ovhAuthenticationRef' is used, 'applicationConsumerKeyRef', 'applicationKeyRef' and 'applicationSecretRef' need to be provided for 'application' authentication method." }} + {{- end }} + + {{- if or (not .applicationConsumerKeyRef.name) (not .applicationConsumerKeyRef.key) }} + {{- fail "Error: When 'ovhAuthenticationRef' is used, you need to provide 'ovhAuthenticationRef.applicationConsumerKeyRef.name' and 'ovhAuthenticationRef.applicationConsumerKeyRef.key'" }} + {{- end }} + {{- if or (not .applicationKeyRef.name) (not .applicationKeyRef.key) }} + {{- fail "Error: When 'ovhAuthenticationRef' is used, you need to provide 'ovhAuthenticationRef.applicationKeyRef.name' and 'ovhAuthenticationRef.applicationKeyRef.key'" }} + {{- end }} + {{- if or (not .applicationSecretRef.name) (not .applicationSecretRef.key) }} + {{- fail "Error: When 'ovhAuthenticationRef' is used, you need to provide 'ovhAuthenticationRef.applicationSecretRef.name' and 'ovhAuthenticationRef.applicationSecretRef.key'" }} + {{- end }} + + {{- else if eq "oauth2" .authenticationMethod }} + {{- if and (not .oauth2ClientIdRef) (not .oauth2ClientSecretRef) }} + {{- fail "Error: When 'ovhAuthenticationRef' is used, 'oauth2ClientIdRef' and 'oauth2ClientSecretRef' need to be provided for 'oauth2' authentication method." }} + {{- end }} + + {{- if or (not .oauth2ClientIdRef.name) (not .oauth2ClientIdRef.key) }} + {{- fail "Error: When 'ovhAuthenticationRef' is used, you need to provide 'ovhAuthenticationRef.oauth2ClientIdRef.name' and 'ovhAuthenticationRef.oauth2ClientIdRef.key'" }} + {{- end }} + {{- if or (not .oauth2ClientSecretRef.name) (not .oauth2ClientSecretRef.key) }} + {{- fail "Error: When 'ovhAuthenticationRef' is used, you need to provide 'ovhAuthenticationRef.oauth2ClientSecretRef.name' and 'ovhAuthenticationRef.oauth2ClientSecretRef.key'" }} + {{- end }} + + {{- else }} + {{- fail "Error: Invalid 'authenticationMethod'. It must be either 'application' or 'oauth2'." }} {{- end }} - {{- eq "true" "true" -}} + {{- true -}} {{- end -}} {{- end -}} diff --git a/charts/cert-manager-webhook-ovh/templates/issuer.yaml b/charts/cert-manager-webhook-ovh/templates/issuer.yaml index 00133e7..bf77ff2 100644 --- a/charts/cert-manager-webhook-ovh/templates/issuer.yaml +++ b/charts/cert-manager-webhook-ovh/templates/issuer.yaml @@ -29,27 +29,48 @@ spec: config: endpoint: {{ .ovhEndpointName | quote }} {{- if eq (include "cert-manager-webhook-ovh.isOvhAuthenticationAvail" .ovhAuthentication) "true" }} + authenticationMethod: {{ .ovhAuthentication.authenticationMethod }} + {{- if eq "application" .ovhAuthentication.authenticationMethod }} applicationKeyRef: name: {{ printf "%s-ovh-credentials" .name }} key: "applicationKey" applicationSecretRef: name: {{ printf "%s-ovh-credentials" .name }} key: "applicationSecret" - consumerKeyRef: + applicationConsumerKeyRef: name: {{ printf "%s-ovh-credentials" .name }} - key: "consumerKey" + key: "applicationConsumerKey" + {{- else if eq "oauth2" .ovhAuthentication.authenticationMethod }} + oauth2ClientIdRef: + name: {{ printf "%s-ovh-credentials" .name }} + key: "oauth2ClientId" + oauth2ClientSecretRef: + name: {{ printf "%s-ovh-credentials" .name }} + key: "oauth2ClientSecret" + {{- end }} {{- end }} + {{- if eq (include "cert-manager-webhook-ovh.isOvhAuthenticationRefAvail" .ovhAuthenticationRef) "true" }} + authenticationMethod: {{ .ovhAuthenticationRef.authenticationMethod }} + {{- if eq "application" .ovhAuthenticationRef.authenticationMethod }} applicationKeyRef: name: {{ .ovhAuthenticationRef.applicationKeyRef.name }} key: {{ .ovhAuthenticationRef.applicationKeyRef.key }} applicationSecretRef: name: {{ .ovhAuthenticationRef.applicationSecretRef.name }} key: {{ .ovhAuthenticationRef.applicationSecretRef.key }} - consumerKeyRef: - name: {{ .ovhAuthenticationRef.consumerKeyRef.name }} - key: {{ .ovhAuthenticationRef.consumerKeyRef.key }} + applicationConsumerKeyRef: + name: {{ .ovhAuthenticationRef.applicationConsumerKeyRef.name }} + key: {{ .ovhAuthenticationRef.applicationConsumerKeyRef.key }} + {{- else if eq "oauth2" .ovhAuthenticationRef.authenticationMethod }} + oauth2ClientIdRef: + name: {{ .ovhAuthenticationRef.oauth2ClientIdRef.name }} + key: {{ .ovhAuthenticationRef.oauth2ClientIdRef.key }} + oauth2ClientSecretRef: + name: {{ .ovhAuthenticationRef.oauth2ClientSecretRef.name }} + key: {{ .ovhAuthenticationRef.oauth2ClientSecretRef.key }} {{- end }} + {{- end }} --- {{- end }}{{/* end if .create */}} {{- end }}{{/* end range */}} diff --git a/charts/cert-manager-webhook-ovh/templates/rbac.yaml b/charts/cert-manager-webhook-ovh/templates/rbac.yaml index dec16ed..5f7ca38 100644 --- a/charts/cert-manager-webhook-ovh/templates/rbac.yaml +++ b/charts/cert-manager-webhook-ovh/templates/rbac.yaml @@ -116,9 +116,14 @@ subjects: {{- $secretsList = append $secretsList (printf "%s-ovh-credentials" .name) | uniq }} {{- end }} {{- if eq (include "cert-manager-webhook-ovh.isOvhAuthenticationRefAvail" .ovhAuthenticationRef) "true" }} - {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationKeyRef.name }} - {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationSecretRef.name }} - {{- $secretsList = append $secretsList .ovhAuthenticationRef.consumerKeyRef.name }} + {{- if eq "application" .ovhAuthenticationRef.authenticationMethod }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationKeyRef.name }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationSecretRef.name }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationConsumerKeyRef.name }} + {{- else if eq "oauth2" .ovhAuthenticationRef.authenticationMethod }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.oauth2ClientIdRef.name }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.oauth2ClientSecretRef.name }} + {{- end }} {{- end }} {{- end }}{{/* end if eq .kind "ClusterIssuer" */}} {{- end }}{{/* end if .create */}} @@ -183,9 +188,14 @@ subjects: {{- $secretsList = append $secretsList (printf "%s-ovh-credentials" .name) }} {{- end }} {{- if eq (include "cert-manager-webhook-ovh.isOvhAuthenticationRefAvail" .ovhAuthenticationRef) "true" }} - {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationKeyRef.name }} - {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationSecretRef.name }} - {{- $secretsList = append $secretsList .ovhAuthenticationRef.consumerKeyRef.name }} + {{- if eq "application" .ovhAuthenticationRef.authenticationMethod }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationKeyRef.name }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationSecretRef.name }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.applicationConsumerKeyRef.name }} + {{- else if eq "oauth2" .ovhAuthenticationRef.authenticationMethod }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.oauth2ClientIdRef.name }} + {{- $secretsList = append $secretsList .ovhAuthenticationRef.oauth2ClientSecretRef.name }} + {{- end }} {{- end }} {{- end }} {{- end }}{{/* end if eq .kind "Issuer" */}} diff --git a/charts/cert-manager-webhook-ovh/templates/secret.yaml b/charts/cert-manager-webhook-ovh/templates/secret.yaml index 14597a2..d4ae759 100644 --- a/charts/cert-manager-webhook-ovh/templates/secret.yaml +++ b/charts/cert-manager-webhook-ovh/templates/secret.yaml @@ -1,6 +1,6 @@ {{- range $.Values.issuers }} {{- if .create }} - {{- if or (and (.ovhAuthentication) (.ovhAuthenticationRef)) (and (not .ovhAuthentication) (not .ovhAuthenticationRef)) }} + {{- if not (or .ovhAuthentication .ovhAuthenticationRef) }} {{ fail "Error: For each issuer you wish to create, you need to define either 'ovhAuthentication' or 'ovhAuthenticationRef'" }} {{- end }} {{- if eq (include "cert-manager-webhook-ovh.isOvhAuthenticationAvail" .ovhAuthentication) "true" }} @@ -17,9 +17,14 @@ metadata: labels: {{- include "cert-manager-webhook-ovh.labels" $ | nindent 4 }} data: + {{- if eq "application" .ovhAuthentication.authenticationMethod }} applicationKey: {{ .ovhAuthentication.applicationKey | b64enc | quote }} applicationSecret: {{ .ovhAuthentication.applicationSecret | b64enc | quote }} consumerKey: {{ .ovhAuthentication.consumerKey | b64enc | quote }} + {{- else if eq "oauth2" .ovhAuthentication.authenticationMethod }} + oauth2ClientId: {{ .ovhAuthentication.oauth2ClientId | b64enc | quote }} + oauth2ClientSecret: {{ .ovhAuthentication.oauth2ClientSecret | b64enc | quote }} + {{- end }} --- {{- end }}{{/* end if eq (include "cert..." */}} {{- end }}{{/* end if .create */}} diff --git a/charts/cert-manager-webhook-ovh/templates/version.yaml b/charts/cert-manager-webhook-ovh/templates/version.yaml index 1e4c101..9f45d94 100644 --- a/charts/cert-manager-webhook-ovh/templates/version.yaml +++ b/charts/cert-manager-webhook-ovh/templates/version.yaml @@ -1,4 +1,4 @@ -{{- $expectedVersion := "0.0.1" -}} +{{- $expectedVersion := "0.0.2" -}} {{- if .Values.configVersion -}} {{- $configVersion := .Values.configVersion | trimAll " " -}} {{- if $configVersion -}} diff --git a/go.sum b/go.sum index 9b69547..97e33e8 100644 --- a/go.sum +++ b/go.sum @@ -121,8 +121,6 @@ github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= -github.com/ovh/go-ovh v1.4.3 h1:Gs3V823zwTFpzgGLZNI6ILS4rmxZgJwJCz54Er9LwD0= -github.com/ovh/go-ovh v1.4.3/go.mod h1:AkPXVtgwB6xlKblMjRKJJmjRp+ogrE7fz2lVgcQY8SY= github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI= github.com/ovh/go-ovh v1.6.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/main.go b/main.go index 622a4a7..d1b64c2 100644 --- a/main.go +++ b/main.go @@ -64,10 +64,13 @@ type ovhDNSProviderSolver struct { // be used by your provider here, you should reference a Kubernetes Secret // resource and fetch these credentials using a Kubernetes clientset. type ovhDNSProviderConfig struct { - Endpoint string `json:"endpoint"` - ApplicationKeyRef corev1.SecretKeySelector `json:"applicationKeyRef"` - ApplicationSecretRef corev1.SecretKeySelector `json:"applicationSecretRef"` - ConsumerKeyRef corev1.SecretKeySelector `json:"consumerKeyRef"` + Endpoint string `json:"endpoint"` + AuthenticationMethod string `json:"authenticationMethod"` + ApplicationKeyRef corev1.SecretKeySelector `json:"applicationKeyRef"` + ApplicationSecretRef corev1.SecretKeySelector `json:"applicationSecretRef"` + ApplicationConsumerKeyRef corev1.SecretKeySelector `json:"applicationConsumerKeyRef"` + OAuth2ClientIdRef corev1.SecretKeySelector `json:"oauth2ClientIdRef"` + OAuth2ClientSecretRef corev1.SecretKeySelector `json:"oauth2ClientSecretRef"` } type ovhZoneStatus struct { @@ -103,14 +106,27 @@ func (s *ovhDNSProviderSolver) validate(cfg *ovhDNSProviderConfig, allowAmbientC if cfg.Endpoint == "" { return errors.New("no endpoint provided in OVH config") } - if cfg.ApplicationKeyRef.Name == "" { - return errors.New("no application key provided in OVH config") - } - if cfg.ApplicationSecretRef.Name == "" { - return errors.New("no application secret provided in OVH config") - } - if cfg.ConsumerKeyRef.Name == "" { - return errors.New("no consumer key provided in OVH config") + + switch cfg.AuthenticationMethod { + case "application": + if cfg.ApplicationKeyRef.Name == "" { + return errors.New("no application key provided in OVH config") + } + if cfg.ApplicationSecretRef.Name == "" { + return errors.New("no application secret provided in OVH config") + } + if cfg.ApplicationConsumerKeyRef.Name == "" { + return errors.New("no consumer key provided in OVH config") + } + case "oauth2": + if cfg.OAuth2ClientIdRef.Name == "" { + return errors.New("no client ID provided in OVH config") + } + if cfg.OAuth2ClientSecretRef.Name == "" { + return errors.New("no client secret provided in OVH config") + } + default: + return errors.New("invalid authentication method provided in OVH config") } logf.Log.Info("Provider config: passed.") return nil @@ -130,22 +146,37 @@ func (s *ovhDNSProviderSolver) ovhClient(ch *v1alpha1.ChallengeRequest) (*ovh.Cl return nil, err } - applicationKey, err := s.secret(cfg.ApplicationKeyRef, ch.ResourceNamespace) - if err != nil { - return nil, err - } + switch cfg.AuthenticationMethod { + case "application": + applicationKey, err := s.secret(cfg.ApplicationKeyRef, ch.ResourceNamespace) + if err != nil { + return nil, err + } - applicationSecret, err := s.secret(cfg.ApplicationSecretRef, ch.ResourceNamespace) - if err != nil { - return nil, err - } + applicationSecret, err := s.secret(cfg.ApplicationSecretRef, ch.ResourceNamespace) + if err != nil { + return nil, err + } - consumerKey, err := s.secret(cfg.ConsumerKeyRef, ch.ResourceNamespace) - if err != nil { - return nil, err + applicationConsumerKey, err := s.secret(cfg.ApplicationConsumerKeyRef, ch.ResourceNamespace) + if err != nil { + return nil, err + } + + return ovh.NewClient(cfg.Endpoint, applicationKey, applicationSecret, applicationConsumerKey) + case "oauth2": + clientId, err := s.secret(cfg.OAuth2ClientIdRef, ch.ResourceNamespace) + if err != nil { + return nil, err + } + clientSecret, err := s.secret(cfg.OAuth2ClientSecretRef, ch.ResourceNamespace) + if err != nil { + return nil, err + } + return ovh.NewOAuth2Client(cfg.Endpoint, clientId, clientSecret) } - return ovh.NewClient(cfg.Endpoint, applicationKey, applicationSecret, consumerKey) + return nil, fmt.Errorf("unknown authentication method %q", cfg.AuthenticationMethod) } func (s *ovhDNSProviderSolver) secret(ref corev1.SecretKeySelector, namespace string) (string, error) {