Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth2 authentication method #49

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/changelog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 }')"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}

Expand Down
4 changes: 2 additions & 2 deletions charts/cert-manager-webhook-ovh/Chart.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,4 +19,4 @@ maintainers:
name: cert-manager-webhook-ovh
sources:
- https://github.com/aureq/cert-manager-webhook-ovh
version: "0.7.0"
version: "0.8.0-alpha.1"
60 changes: 45 additions & 15 deletions charts/cert-manager-webhook-ovh/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -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 -}}

Expand All @@ -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 -}}

Expand Down
31 changes: 26 additions & 5 deletions charts/cert-manager-webhook-ovh/templates/issuer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 */}}
22 changes: 16 additions & 6 deletions charts/cert-manager-webhook-ovh/templates/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 */}}
Expand Down Expand Up @@ -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" */}}
Expand Down
7 changes: 6 additions & 1 deletion charts/cert-manager-webhook-ovh/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -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" }}
Expand All @@ -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 */}}
Expand Down
2 changes: 1 addition & 1 deletion charts/cert-manager-webhook-ovh/templates/version.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- $expectedVersion := "0.0.1" -}}
{{- $expectedVersion := "0.0.2" -}}
{{- if .Values.configVersion -}}
{{- $configVersion := .Values.configVersion | trimAll " " -}}
{{- if $configVersion -}}
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
79 changes: 55 additions & 24 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand Down