diff --git a/deploy/crds/crd-clusterissuers.yaml b/deploy/crds/crd-clusterissuers.yaml index 80f330459..118272ef5 100644 --- a/deploy/crds/crd-clusterissuers.yaml +++ b/deploy/crds/crd-clusterissuers.yaml @@ -1139,24 +1139,20 @@ spec: description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string caBundle: - description: PEM-encoded CA bundle (base64-encoded) used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection. + description: PEM-encoded CA bundle (base64-encoded) used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection. Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, the cert-manager controller system root certificates are used to validate the TLS connection. type: string format: byte caBundleSecretRef: - description: Like CABundle but loads the CA bundle from a Kubernetes Secret. CABundle will take precedence if also set. + description: CABundleSecretRef is a reference to a Secret which contains the CABundle which will be used when connecting to Vault when using HTTPS. Mutually exclusive with CABundle. If neither CABundleSecretRef nor CABundle are defined, the cert-manager controller system root certificates are used to validate the TLS connection. If no key for the Secret is specified, cert-manager will default to 'ca.crt'. type: object required: - - key - name properties: key: - description: The key of the entry in the Secret resource's `data` field to be used. + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. type: string name: - description: The name of the Secret resource being referred to. - type: string - namespace: - description: The namespace of the Secret resource being referred to. If omitted, it will use the namespace of the referent. If the referent is a cluster-scoped resource (e.g. a ClusterIssuer), the namespace of the configured 'cluster resource namespace' will be used. It is set as a flag on the controller component (and defaults to the namespace that cert-manager runs in). + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string namespace: description: 'Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: "ns1" More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces' diff --git a/deploy/crds/crd-issuers.yaml b/deploy/crds/crd-issuers.yaml index a86ef3a58..bc4c0f4fc 100644 --- a/deploy/crds/crd-issuers.yaml +++ b/deploy/crds/crd-issuers.yaml @@ -1139,24 +1139,20 @@ spec: description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string caBundle: - description: PEM-encoded CA bundle (base64-encoded) used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection. + description: PEM-encoded CA bundle (base64-encoded) used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection. Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, the cert-manager controller system root certificates are used to validate the TLS connection. type: string format: byte caBundleSecretRef: - description: Like CABundle but loads the CA bundle from a Kubernetes Secret. CABundle will take precedence if also set. + description: CABundleSecretRef is a reference to a Secret which contains the CABundle which will be used when connecting to Vault when using HTTPS. Mutually exclusive with CABundle. If neither CABundleSecretRef nor CABundle are defined, the cert-manager controller system root certificates are used to validate the TLS connection. If no key for the Secret is specified, cert-manager will default to 'ca.crt'. type: object required: - - key - name properties: key: - description: The key of the entry in the Secret resource's `data` field to be used. + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. type: string name: - description: The name of the Secret resource being referred to. - type: string - namespace: - description: The namespace of the Secret resource being referred to. If omitted, it will use the namespace of the referent. If the referent is a cluster-scoped resource (e.g. a ClusterIssuer), the namespace of the configured 'cluster resource namespace' will be used. It is set as a flag on the controller component (and defaults to the namespace that cert-manager runs in). + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string namespace: description: 'Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: "ns1" More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces' diff --git a/internal/apis/certmanager/types_issuer.go b/internal/apis/certmanager/types_issuer.go index 9c5873b86..786a52d14 100644 --- a/internal/apis/certmanager/types_issuer.go +++ b/internal/apis/certmanager/types_issuer.go @@ -186,28 +186,18 @@ type VaultIssuer struct { // certificate. Only used if the Server URL is using HTTPS protocol. This // parameter is ignored for plain HTTP protocol connection. If not set the // system root certificates are used to validate the TLS connection. + // Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, + // the cert-manager controller system root certificates are used to validate the TLS connection. + // +optional CABundle []byte - // Like CABundle but loads the CA bundle from a Kubernetes Secret. - // CABundle will take precedence if also set. + // CABundleSecretRef is a reference to a Secret which contains the CABundle which will be used when + // connecting to Vault when using HTTPS. + // Mutually exclusive with CABundle. If neither CABundleSecretRef nor CABundle are defined, the cert-manager + // controller system root certificates are used to validate the TLS connection. + // If no key for the Secret is specified, cert-manager will default to 'ca.crt'. // +optional - CABundleSecretRef VaultCaBundleSecretRef -} - -// VaultCaBundleSecretRef configures a Vault CA bundle via a Kubernetes Secret. -type VaultCaBundleSecretRef struct { - // The name of the Secret resource being referred to. - Name string `json:"name"` - - // The namespace of the Secret resource being referred to. - // If omitted, it will use the namespace of the referent. If the referent - // is a cluster-scoped resource (e.g. a ClusterIssuer), the namespace of - // the configured 'cluster resource namespace' will be used. It is set as a - // flag on the controller component (and defaults to the namespace that cert-manager runs in). - Namespace string `json:"namespace,omitempty""` - - // The key of the entry in the Secret resource's `data` field to be used. - Key string `json:"key"` + CABundleSecretRef *cmmeta.SecretKeySelector } // VaultAuth is configuration used to authenticate with a Vault server. diff --git a/internal/apis/certmanager/v1/zz_generated.conversion.go b/internal/apis/certmanager/v1/zz_generated.conversion.go index 812ec3e6e..9c0051e8d 100644 --- a/internal/apis/certmanager/v1/zz_generated.conversion.go +++ b/internal/apis/certmanager/v1/zz_generated.conversion.go @@ -314,16 +314,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.VaultCaBundleSecretRef)(nil), (*certmanager.VaultCaBundleSecretRef)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(a.(*v1.VaultCaBundleSecretRef), b.(*certmanager.VaultCaBundleSecretRef), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*certmanager.VaultCaBundleSecretRef)(nil), (*v1.VaultCaBundleSecretRef)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_certmanager_VaultCaBundleSecretRef_To_v1_VaultCaBundleSecretRef(a.(*certmanager.VaultCaBundleSecretRef), b.(*v1.VaultCaBundleSecretRef), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*v1.VaultIssuer)(nil), (*certmanager.VaultIssuer)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_VaultIssuer_To_certmanager_VaultIssuer(a.(*v1.VaultIssuer), b.(*certmanager.VaultIssuer), scope) }); err != nil { @@ -1387,30 +1377,6 @@ func Convert_certmanager_VaultAuth_To_v1_VaultAuth(in *certmanager.VaultAuth, ou return autoConvert_certmanager_VaultAuth_To_v1_VaultAuth(in, out, s) } -func autoConvert_v1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in *v1.VaultCaBundleSecretRef, out *certmanager.VaultCaBundleSecretRef, s conversion.Scope) error { - out.Name = in.Name - out.Namespace = in.Namespace - out.Key = in.Key - return nil -} - -// Convert_v1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef is an autogenerated conversion function. -func Convert_v1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in *v1.VaultCaBundleSecretRef, out *certmanager.VaultCaBundleSecretRef, s conversion.Scope) error { - return autoConvert_v1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in, out, s) -} - -func autoConvert_certmanager_VaultCaBundleSecretRef_To_v1_VaultCaBundleSecretRef(in *certmanager.VaultCaBundleSecretRef, out *v1.VaultCaBundleSecretRef, s conversion.Scope) error { - out.Name = in.Name - out.Namespace = in.Namespace - out.Key = in.Key - return nil -} - -// Convert_certmanager_VaultCaBundleSecretRef_To_v1_VaultCaBundleSecretRef is an autogenerated conversion function. -func Convert_certmanager_VaultCaBundleSecretRef_To_v1_VaultCaBundleSecretRef(in *certmanager.VaultCaBundleSecretRef, out *v1.VaultCaBundleSecretRef, s conversion.Scope) error { - return autoConvert_certmanager_VaultCaBundleSecretRef_To_v1_VaultCaBundleSecretRef(in, out, s) -} - func autoConvert_v1_VaultIssuer_To_certmanager_VaultIssuer(in *v1.VaultIssuer, out *certmanager.VaultIssuer, s conversion.Scope) error { if err := Convert_v1_VaultAuth_To_certmanager_VaultAuth(&in.Auth, &out.Auth, s); err != nil { return err @@ -1419,8 +1385,14 @@ func autoConvert_v1_VaultIssuer_To_certmanager_VaultIssuer(in *v1.VaultIssuer, o out.Path = in.Path out.Namespace = in.Namespace out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) - if err := Convert_v1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(&in.CABundleSecretRef, &out.CABundleSecretRef, s); err != nil { - return err + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(meta.SecretKeySelector) + if err := internalapismetav1.Convert_v1_SecretKeySelector_To_meta_SecretKeySelector(*in, *out, s); err != nil { + return err + } + } else { + out.CABundleSecretRef = nil } return nil } @@ -1438,8 +1410,14 @@ func autoConvert_certmanager_VaultIssuer_To_v1_VaultIssuer(in *certmanager.Vault out.Path = in.Path out.Namespace = in.Namespace out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) - if err := Convert_certmanager_VaultCaBundleSecretRef_To_v1_VaultCaBundleSecretRef(&in.CABundleSecretRef, &out.CABundleSecretRef, s); err != nil { - return err + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(apismetav1.SecretKeySelector) + if err := internalapismetav1.Convert_meta_SecretKeySelector_To_v1_SecretKeySelector(*in, *out, s); err != nil { + return err + } + } else { + out.CABundleSecretRef = nil } return nil } diff --git a/internal/apis/certmanager/v1alpha2/types_issuer.go b/internal/apis/certmanager/v1alpha2/types_issuer.go index 39aa066f1..90893c1cf 100644 --- a/internal/apis/certmanager/v1alpha2/types_issuer.go +++ b/internal/apis/certmanager/v1alpha2/types_issuer.go @@ -203,29 +203,18 @@ type VaultIssuer struct { // certificate. Only used if the Server URL is using HTTPS protocol. This // parameter is ignored for plain HTTP protocol connection. If not set the // system root certificates are used to validate the TLS connection. + // Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, + // the cert-manager controller system root certificates are used to validate the TLS connection. // +optional CABundle []byte `json:"caBundle,omitempty"` - // Like CABundle but loads the CA bundle from a Kubernetes Secret. - // CABundle will take precedence if also set. + // CABundleSecretRef is a reference to a Secret which contains the CABundle which will be used when + // connecting to Vault when using HTTPS. + // Mutually exclusive with CABundle. If neither CABundleSecretRef nor CABundle are defined, the cert-manager + // controller system root certificates are used to validate the TLS connection. + // If no key for the Secret is specified, cert-manager will default to 'ca.crt'. // +optional - CABundleSecretRef VaultCaBundleSecretRef -} - -// VaultCaBundleSecretRef configures a Vault CA bundle via a Kubernetes Secret. -type VaultCaBundleSecretRef struct { - // The name of the Secret resource being referred to. - Name string `json:"name"` - - // The namespace of the Secret resource being referred to. - // If omitted, it will use the namespace of the referent. If the referent - // is a cluster-scoped resource (e.g. a ClusterIssuer), the namespace of - // the configured 'cluster resource namespace' will be used. It is set as a - // flag on the controller component (and defaults to the namespace that cert-manager runs in). - Namespace string `json:"namespace,omitempty""` - - // The key of the entry in the Secret resource's `data` field to be used. - Key string `json:"key"` + CABundleSecretRef *cmmeta.SecretKeySelector `json:"caBundleSecretRef,omitempty"` } // Configuration used to authenticate with a Vault server. diff --git a/internal/apis/certmanager/v1alpha2/zz_generated.conversion.go b/internal/apis/certmanager/v1alpha2/zz_generated.conversion.go index 6e54c8a45..f78c39372 100644 --- a/internal/apis/certmanager/v1alpha2/zz_generated.conversion.go +++ b/internal/apis/certmanager/v1alpha2/zz_generated.conversion.go @@ -297,16 +297,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*VaultCaBundleSecretRef)(nil), (*certmanager.VaultCaBundleSecretRef)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha2_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(a.(*VaultCaBundleSecretRef), b.(*certmanager.VaultCaBundleSecretRef), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*certmanager.VaultCaBundleSecretRef)(nil), (*VaultCaBundleSecretRef)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_certmanager_VaultCaBundleSecretRef_To_v1alpha2_VaultCaBundleSecretRef(a.(*certmanager.VaultCaBundleSecretRef), b.(*VaultCaBundleSecretRef), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*VaultIssuer)(nil), (*certmanager.VaultIssuer)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_VaultIssuer_To_certmanager_VaultIssuer(a.(*VaultIssuer), b.(*certmanager.VaultIssuer), scope) }); err != nil { @@ -1403,30 +1393,6 @@ func Convert_certmanager_VaultAuth_To_v1alpha2_VaultAuth(in *certmanager.VaultAu return autoConvert_certmanager_VaultAuth_To_v1alpha2_VaultAuth(in, out, s) } -func autoConvert_v1alpha2_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in *VaultCaBundleSecretRef, out *certmanager.VaultCaBundleSecretRef, s conversion.Scope) error { - out.Name = in.Name - out.Namespace = in.Namespace - out.Key = in.Key - return nil -} - -// Convert_v1alpha2_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef is an autogenerated conversion function. -func Convert_v1alpha2_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in *VaultCaBundleSecretRef, out *certmanager.VaultCaBundleSecretRef, s conversion.Scope) error { - return autoConvert_v1alpha2_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in, out, s) -} - -func autoConvert_certmanager_VaultCaBundleSecretRef_To_v1alpha2_VaultCaBundleSecretRef(in *certmanager.VaultCaBundleSecretRef, out *VaultCaBundleSecretRef, s conversion.Scope) error { - out.Name = in.Name - out.Namespace = in.Namespace - out.Key = in.Key - return nil -} - -// Convert_certmanager_VaultCaBundleSecretRef_To_v1alpha2_VaultCaBundleSecretRef is an autogenerated conversion function. -func Convert_certmanager_VaultCaBundleSecretRef_To_v1alpha2_VaultCaBundleSecretRef(in *certmanager.VaultCaBundleSecretRef, out *VaultCaBundleSecretRef, s conversion.Scope) error { - return autoConvert_certmanager_VaultCaBundleSecretRef_To_v1alpha2_VaultCaBundleSecretRef(in, out, s) -} - func autoConvert_v1alpha2_VaultIssuer_To_certmanager_VaultIssuer(in *VaultIssuer, out *certmanager.VaultIssuer, s conversion.Scope) error { if err := Convert_v1alpha2_VaultAuth_To_certmanager_VaultAuth(&in.Auth, &out.Auth, s); err != nil { return err @@ -1435,8 +1401,14 @@ func autoConvert_v1alpha2_VaultIssuer_To_certmanager_VaultIssuer(in *VaultIssuer out.Path = in.Path out.Namespace = in.Namespace out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) - if err := Convert_v1alpha2_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(&in.CABundleSecretRef, &out.CABundleSecretRef, s); err != nil { - return err + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(meta.SecretKeySelector) + if err := apismetav1.Convert_v1_SecretKeySelector_To_meta_SecretKeySelector(*in, *out, s); err != nil { + return err + } + } else { + out.CABundleSecretRef = nil } return nil } @@ -1454,8 +1426,14 @@ func autoConvert_certmanager_VaultIssuer_To_v1alpha2_VaultIssuer(in *certmanager out.Path = in.Path out.Namespace = in.Namespace out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) - if err := Convert_certmanager_VaultCaBundleSecretRef_To_v1alpha2_VaultCaBundleSecretRef(&in.CABundleSecretRef, &out.CABundleSecretRef, s); err != nil { - return err + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(metav1.SecretKeySelector) + if err := apismetav1.Convert_meta_SecretKeySelector_To_v1_SecretKeySelector(*in, *out, s); err != nil { + return err + } + } else { + out.CABundleSecretRef = nil } return nil } diff --git a/internal/apis/certmanager/v1alpha2/zz_generated.deepcopy.go b/internal/apis/certmanager/v1alpha2/zz_generated.deepcopy.go index 1b01c6696..a8e69faa2 100644 --- a/internal/apis/certmanager/v1alpha2/zz_generated.deepcopy.go +++ b/internal/apis/certmanager/v1alpha2/zz_generated.deepcopy.go @@ -870,22 +870,6 @@ func (in *VaultAuth) DeepCopy() *VaultAuth { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VaultCaBundleSecretRef) DeepCopyInto(out *VaultCaBundleSecretRef) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultCaBundleSecretRef. -func (in *VaultCaBundleSecretRef) DeepCopy() *VaultCaBundleSecretRef { - if in == nil { - return nil - } - out := new(VaultCaBundleSecretRef) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = *in @@ -895,7 +879,11 @@ func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = make([]byte, len(*in)) copy(*out, *in) } - out.CABundleSecretRef = in.CABundleSecretRef + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(metav1.SecretKeySelector) + **out = **in + } return } diff --git a/internal/apis/certmanager/v1alpha3/types_issuer.go b/internal/apis/certmanager/v1alpha3/types_issuer.go index eb6772064..29ccd7ac5 100644 --- a/internal/apis/certmanager/v1alpha3/types_issuer.go +++ b/internal/apis/certmanager/v1alpha3/types_issuer.go @@ -203,29 +203,18 @@ type VaultIssuer struct { // certificate. Only used if the Server URL is using HTTPS protocol. This // parameter is ignored for plain HTTP protocol connection. If not set the // system root certificates are used to validate the TLS connection. + // Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, + // the cert-manager controller system root certificates are used to validate the TLS connection. // +optional CABundle []byte `json:"caBundle,omitempty"` - // Like CABundle but loads the CA bundle from a Kubernetes Secret. - // CABundle will take precedence if also set. + // CABundleSecretRef is a reference to a Secret which contains the CABundle which will be used when + // connecting to Vault when using HTTPS. + // Mutually exclusive with CABundle. If neither CABundleSecretRef nor CABundle are defined, the cert-manager + // controller system root certificates are used to validate the TLS connection. + // If no key for the Secret is specified, cert-manager will default to 'ca.crt'. // +optional - CABundleSecretRef VaultCaBundleSecretRef -} - -// VaultCaBundleSecretRef configures a Vault CA bundle via a Kubernetes Secret. -type VaultCaBundleSecretRef struct { - // The name of the Secret resource being referred to. - Name string `json:"name"` - - // The namespace of the Secret resource being referred to. - // If omitted, it will use the namespace of the referent. If the referent - // is a cluster-scoped resource (e.g. a ClusterIssuer), the namespace of - // the configured 'cluster resource namespace' will be used. It is set as a - // flag on the controller component (and defaults to the namespace that cert-manager runs in). - Namespace string `json:"namespace,omitempty""` - - // The key of the entry in the Secret resource's `data` field to be used. - Key string `json:"key"` + CABundleSecretRef *cmmeta.SecretKeySelector `json:"caBundleSecretRef,omitempty"` } // Configuration used to authenticate with a Vault server. diff --git a/internal/apis/certmanager/v1alpha3/zz_generated.conversion.go b/internal/apis/certmanager/v1alpha3/zz_generated.conversion.go index 5fc8c3777..844ae394e 100644 --- a/internal/apis/certmanager/v1alpha3/zz_generated.conversion.go +++ b/internal/apis/certmanager/v1alpha3/zz_generated.conversion.go @@ -297,16 +297,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*VaultCaBundleSecretRef)(nil), (*certmanager.VaultCaBundleSecretRef)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha3_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(a.(*VaultCaBundleSecretRef), b.(*certmanager.VaultCaBundleSecretRef), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*certmanager.VaultCaBundleSecretRef)(nil), (*VaultCaBundleSecretRef)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_certmanager_VaultCaBundleSecretRef_To_v1alpha3_VaultCaBundleSecretRef(a.(*certmanager.VaultCaBundleSecretRef), b.(*VaultCaBundleSecretRef), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*VaultIssuer)(nil), (*certmanager.VaultIssuer)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_VaultIssuer_To_certmanager_VaultIssuer(a.(*VaultIssuer), b.(*certmanager.VaultIssuer), scope) }); err != nil { @@ -1402,30 +1392,6 @@ func Convert_certmanager_VaultAuth_To_v1alpha3_VaultAuth(in *certmanager.VaultAu return autoConvert_certmanager_VaultAuth_To_v1alpha3_VaultAuth(in, out, s) } -func autoConvert_v1alpha3_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in *VaultCaBundleSecretRef, out *certmanager.VaultCaBundleSecretRef, s conversion.Scope) error { - out.Name = in.Name - out.Namespace = in.Namespace - out.Key = in.Key - return nil -} - -// Convert_v1alpha3_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef is an autogenerated conversion function. -func Convert_v1alpha3_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in *VaultCaBundleSecretRef, out *certmanager.VaultCaBundleSecretRef, s conversion.Scope) error { - return autoConvert_v1alpha3_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in, out, s) -} - -func autoConvert_certmanager_VaultCaBundleSecretRef_To_v1alpha3_VaultCaBundleSecretRef(in *certmanager.VaultCaBundleSecretRef, out *VaultCaBundleSecretRef, s conversion.Scope) error { - out.Name = in.Name - out.Namespace = in.Namespace - out.Key = in.Key - return nil -} - -// Convert_certmanager_VaultCaBundleSecretRef_To_v1alpha3_VaultCaBundleSecretRef is an autogenerated conversion function. -func Convert_certmanager_VaultCaBundleSecretRef_To_v1alpha3_VaultCaBundleSecretRef(in *certmanager.VaultCaBundleSecretRef, out *VaultCaBundleSecretRef, s conversion.Scope) error { - return autoConvert_certmanager_VaultCaBundleSecretRef_To_v1alpha3_VaultCaBundleSecretRef(in, out, s) -} - func autoConvert_v1alpha3_VaultIssuer_To_certmanager_VaultIssuer(in *VaultIssuer, out *certmanager.VaultIssuer, s conversion.Scope) error { if err := Convert_v1alpha3_VaultAuth_To_certmanager_VaultAuth(&in.Auth, &out.Auth, s); err != nil { return err @@ -1434,8 +1400,14 @@ func autoConvert_v1alpha3_VaultIssuer_To_certmanager_VaultIssuer(in *VaultIssuer out.Path = in.Path out.Namespace = in.Namespace out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) - if err := Convert_v1alpha3_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(&in.CABundleSecretRef, &out.CABundleSecretRef, s); err != nil { - return err + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(meta.SecretKeySelector) + if err := apismetav1.Convert_v1_SecretKeySelector_To_meta_SecretKeySelector(*in, *out, s); err != nil { + return err + } + } else { + out.CABundleSecretRef = nil } return nil } @@ -1453,8 +1425,14 @@ func autoConvert_certmanager_VaultIssuer_To_v1alpha3_VaultIssuer(in *certmanager out.Path = in.Path out.Namespace = in.Namespace out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) - if err := Convert_certmanager_VaultCaBundleSecretRef_To_v1alpha3_VaultCaBundleSecretRef(&in.CABundleSecretRef, &out.CABundleSecretRef, s); err != nil { - return err + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(metav1.SecretKeySelector) + if err := apismetav1.Convert_meta_SecretKeySelector_To_v1_SecretKeySelector(*in, *out, s); err != nil { + return err + } + } else { + out.CABundleSecretRef = nil } return nil } diff --git a/internal/apis/certmanager/v1alpha3/zz_generated.deepcopy.go b/internal/apis/certmanager/v1alpha3/zz_generated.deepcopy.go index 8325882a9..36d7391ca 100644 --- a/internal/apis/certmanager/v1alpha3/zz_generated.deepcopy.go +++ b/internal/apis/certmanager/v1alpha3/zz_generated.deepcopy.go @@ -865,22 +865,6 @@ func (in *VaultAuth) DeepCopy() *VaultAuth { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VaultCaBundleSecretRef) DeepCopyInto(out *VaultCaBundleSecretRef) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultCaBundleSecretRef. -func (in *VaultCaBundleSecretRef) DeepCopy() *VaultCaBundleSecretRef { - if in == nil { - return nil - } - out := new(VaultCaBundleSecretRef) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = *in @@ -890,7 +874,11 @@ func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = make([]byte, len(*in)) copy(*out, *in) } - out.CABundleSecretRef = in.CABundleSecretRef + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(metav1.SecretKeySelector) + **out = **in + } return } diff --git a/internal/apis/certmanager/v1beta1/types_issuer.go b/internal/apis/certmanager/v1beta1/types_issuer.go index c4c3851d0..baec4fdca 100644 --- a/internal/apis/certmanager/v1beta1/types_issuer.go +++ b/internal/apis/certmanager/v1beta1/types_issuer.go @@ -205,29 +205,18 @@ type VaultIssuer struct { // certificate. Only used if the Server URL is using HTTPS protocol. This // parameter is ignored for plain HTTP protocol connection. If not set the // system root certificates are used to validate the TLS connection. + // Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, + // the cert-manager controller system root certificates are used to validate the TLS connection. // +optional CABundle []byte `json:"caBundle,omitempty"` - // Like CABundle but loads the CA bundle from a Kubernetes Secret. - // CABundle will take precedence if also set. + // CABundleSecretRef is a reference to a Secret which contains the CABundle which will be used when + // connecting to Vault when using HTTPS. + // Mutually exclusive with CABundle. If neither CABundleSecretRef nor CABundle are defined, the cert-manager + // controller system root certificates are used to validate the TLS connection. + // If no key for the Secret is specified, cert-manager will default to 'ca.crt'. // +optional - CABundleSecretRef VaultCaBundleSecretRef -} - -// VaultCaBundleSecretRef configures a Vault CA bundle via a Kubernetes Secret. -type VaultCaBundleSecretRef struct { - // The name of the Secret resource being referred to. - Name string `json:"name"` - - // The namespace of the Secret resource being referred to. - // If omitted, it will use the namespace of the referent. If the referent - // is a cluster-scoped resource (e.g. a ClusterIssuer), the namespace of - // the configured 'cluster resource namespace' will be used. It is set as a - // flag on the controller component (and defaults to the namespace that cert-manager runs in). - Namespace string `json:"namespace,omitempty""` - - // The key of the entry in the Secret resource's `data` field to be used. - Key string `json:"key"` + CABundleSecretRef *cmmeta.SecretKeySelector `json:"caBundleSecretRef,omitempty"` } // Configuration used to authenticate with a Vault server. diff --git a/internal/apis/certmanager/v1beta1/zz_generated.conversion.go b/internal/apis/certmanager/v1beta1/zz_generated.conversion.go index a3f4d3e40..3ddc74291 100644 --- a/internal/apis/certmanager/v1beta1/zz_generated.conversion.go +++ b/internal/apis/certmanager/v1beta1/zz_generated.conversion.go @@ -322,16 +322,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*VaultCaBundleSecretRef)(nil), (*certmanager.VaultCaBundleSecretRef)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(a.(*VaultCaBundleSecretRef), b.(*certmanager.VaultCaBundleSecretRef), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*certmanager.VaultCaBundleSecretRef)(nil), (*VaultCaBundleSecretRef)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_certmanager_VaultCaBundleSecretRef_To_v1beta1_VaultCaBundleSecretRef(a.(*certmanager.VaultCaBundleSecretRef), b.(*VaultCaBundleSecretRef), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*VaultIssuer)(nil), (*certmanager.VaultIssuer)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_VaultIssuer_To_certmanager_VaultIssuer(a.(*VaultIssuer), b.(*certmanager.VaultIssuer), scope) }); err != nil { @@ -1395,30 +1385,6 @@ func Convert_certmanager_VaultAuth_To_v1beta1_VaultAuth(in *certmanager.VaultAut return autoConvert_certmanager_VaultAuth_To_v1beta1_VaultAuth(in, out, s) } -func autoConvert_v1beta1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in *VaultCaBundleSecretRef, out *certmanager.VaultCaBundleSecretRef, s conversion.Scope) error { - out.Name = in.Name - out.Namespace = in.Namespace - out.Key = in.Key - return nil -} - -// Convert_v1beta1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef is an autogenerated conversion function. -func Convert_v1beta1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in *VaultCaBundleSecretRef, out *certmanager.VaultCaBundleSecretRef, s conversion.Scope) error { - return autoConvert_v1beta1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(in, out, s) -} - -func autoConvert_certmanager_VaultCaBundleSecretRef_To_v1beta1_VaultCaBundleSecretRef(in *certmanager.VaultCaBundleSecretRef, out *VaultCaBundleSecretRef, s conversion.Scope) error { - out.Name = in.Name - out.Namespace = in.Namespace - out.Key = in.Key - return nil -} - -// Convert_certmanager_VaultCaBundleSecretRef_To_v1beta1_VaultCaBundleSecretRef is an autogenerated conversion function. -func Convert_certmanager_VaultCaBundleSecretRef_To_v1beta1_VaultCaBundleSecretRef(in *certmanager.VaultCaBundleSecretRef, out *VaultCaBundleSecretRef, s conversion.Scope) error { - return autoConvert_certmanager_VaultCaBundleSecretRef_To_v1beta1_VaultCaBundleSecretRef(in, out, s) -} - func autoConvert_v1beta1_VaultIssuer_To_certmanager_VaultIssuer(in *VaultIssuer, out *certmanager.VaultIssuer, s conversion.Scope) error { if err := Convert_v1beta1_VaultAuth_To_certmanager_VaultAuth(&in.Auth, &out.Auth, s); err != nil { return err @@ -1427,8 +1393,14 @@ func autoConvert_v1beta1_VaultIssuer_To_certmanager_VaultIssuer(in *VaultIssuer, out.Path = in.Path out.Namespace = in.Namespace out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) - if err := Convert_v1beta1_VaultCaBundleSecretRef_To_certmanager_VaultCaBundleSecretRef(&in.CABundleSecretRef, &out.CABundleSecretRef, s); err != nil { - return err + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(meta.SecretKeySelector) + if err := apismetav1.Convert_v1_SecretKeySelector_To_meta_SecretKeySelector(*in, *out, s); err != nil { + return err + } + } else { + out.CABundleSecretRef = nil } return nil } @@ -1446,8 +1418,14 @@ func autoConvert_certmanager_VaultIssuer_To_v1beta1_VaultIssuer(in *certmanager. out.Path = in.Path out.Namespace = in.Namespace out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle)) - if err := Convert_certmanager_VaultCaBundleSecretRef_To_v1beta1_VaultCaBundleSecretRef(&in.CABundleSecretRef, &out.CABundleSecretRef, s); err != nil { - return err + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(metav1.SecretKeySelector) + if err := apismetav1.Convert_meta_SecretKeySelector_To_v1_SecretKeySelector(*in, *out, s); err != nil { + return err + } + } else { + out.CABundleSecretRef = nil } return nil } diff --git a/internal/apis/certmanager/v1beta1/zz_generated.deepcopy.go b/internal/apis/certmanager/v1beta1/zz_generated.deepcopy.go index 01d674061..9eeea27d9 100644 --- a/internal/apis/certmanager/v1beta1/zz_generated.deepcopy.go +++ b/internal/apis/certmanager/v1beta1/zz_generated.deepcopy.go @@ -865,22 +865,6 @@ func (in *VaultAuth) DeepCopy() *VaultAuth { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VaultCaBundleSecretRef) DeepCopyInto(out *VaultCaBundleSecretRef) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultCaBundleSecretRef. -func (in *VaultCaBundleSecretRef) DeepCopy() *VaultCaBundleSecretRef { - if in == nil { - return nil - } - out := new(VaultCaBundleSecretRef) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = *in @@ -890,7 +874,11 @@ func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = make([]byte, len(*in)) copy(*out, *in) } - out.CABundleSecretRef = in.CABundleSecretRef + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(metav1.SecretKeySelector) + **out = **in + } return } diff --git a/internal/apis/certmanager/validation/issuer.go b/internal/apis/certmanager/validation/issuer.go index e8691d2ed..a8513a63f 100644 --- a/internal/apis/certmanager/validation/issuer.go +++ b/internal/apis/certmanager/validation/issuer.go @@ -243,6 +243,11 @@ func ValidateVaultIssuerConfig(iss *certmanager.VaultIssuer, fldPath *field.Path } } + if len(iss.CABundle) > 0 && iss.CABundleSecretRef != nil { + el = append(el, field.Invalid(fldPath.Child("caBundle"), "", "Specified caBundle and caBundleSecretRef cannot be used together")) + el = append(el, field.Invalid(fldPath.Child("caBundleSecretRef"), "", "Specified caBundleSecretRef and caBundle cannot be used together")) + } + return el // TODO: add validation for Vault authentication types } diff --git a/internal/apis/certmanager/zz_generated.deepcopy.go b/internal/apis/certmanager/zz_generated.deepcopy.go index 7e5bba167..121a2b524 100644 --- a/internal/apis/certmanager/zz_generated.deepcopy.go +++ b/internal/apis/certmanager/zz_generated.deepcopy.go @@ -865,22 +865,6 @@ func (in *VaultAuth) DeepCopy() *VaultAuth { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VaultCaBundleSecretRef) DeepCopyInto(out *VaultCaBundleSecretRef) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultCaBundleSecretRef. -func (in *VaultCaBundleSecretRef) DeepCopy() *VaultCaBundleSecretRef { - if in == nil { - return nil - } - out := new(VaultCaBundleSecretRef) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = *in @@ -890,7 +874,11 @@ func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = make([]byte, len(*in)) copy(*out, *in) } - out.CABundleSecretRef = in.CABundleSecretRef + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(meta.SecretKeySelector) + **out = **in + } return } diff --git a/internal/vault/vault.go b/internal/vault/vault.go index 5b6265989..01639cf48 100644 --- a/internal/vault/vault.go +++ b/internal/vault/vault.go @@ -188,7 +188,7 @@ func (v *Vault) newConfig() (*vault.Config, error) { certs := v.issuer.GetSpec().Vault.CABundle if len(certs) == 0 { var err error - if v.issuer.GetSpec().Vault.CABundleSecretRef.Name != "" { + if v.issuer.GetSpec().Vault.CABundleSecretRef != nil { certs, err = v.caBundleFromSecret() if err != nil { return nil, err @@ -212,21 +212,21 @@ func (v *Vault) newConfig() (*vault.Config, error) { func (v *Vault) caBundleFromSecret() ([]byte, error) { ref := v.issuer.GetSpec().Vault.CABundleSecretRef - var namespace string - if ref.Namespace != "" { - namespace = ref.Namespace - } else { - namespace = v.namespace - } - - secret, err := v.secretsLister.Secrets(namespace).Get(ref.Name) + secret, err := v.secretsLister.Secrets(v.namespace).Get(ref.Name) if err != nil { - return nil, fmt.Errorf("could not access secret '%s/%s'", namespace, ref.Name) + return nil, fmt.Errorf("could not access secret '%s/%s': %s", v.namespace, ref.Name, err) } - certBytes, ok := secret.Data[ref.Key] + var key string + if ref.Key != "" { + key = ref.Key + } else { + key = "ca.crt" + } + + certBytes, ok := secret.Data[key] if !ok { - return nil, fmt.Errorf("no data for %q in secret '%s/%s'", ref.Key, namespace, ref.Name) + return nil, fmt.Errorf("no data for %q in secret '%s/%s'", key, v.namespace, ref.Name) } return certBytes, nil diff --git a/internal/vault/vault_test.go b/internal/vault/vault_test.go index 09af668e0..54818bbc9 100644 --- a/internal/vault/vault_test.go +++ b/internal/vault/vault_test.go @@ -28,6 +28,7 @@ import ( "errors" "fmt" "io" + clientcorev1 "k8s.io/client-go/listers/core/v1" "net/http" "strings" "testing" @@ -878,10 +879,29 @@ func TestTokenRef(t *testing.T) { type testNewConfigT struct { expectedErr error issuer *cmapi.Issuer - checkFunc func(cfg *vault.Config) error + checkFunc func(cfg *vault.Config, err error) error + + fakeLister *listers.FakeSecretLister } func TestNewConfig(t *testing.T) { + caBundleSecretRefFakeSecretLister := func(namespace, secret, key, cert string) *listers.FakeSecretLister { + return listers.FakeSecretListerFrom(listers.NewFakeSecretLister(), func(f *listers.FakeSecretLister) { + f.SecretsFn = func(namespace string) clientcorev1.SecretNamespaceLister { + return listers.FakeSecretNamespaceListerFrom(listers.NewFakeSecretNamespaceLister(), func(fn *listers.FakeSecretNamespaceLister) { + fn.GetFn = func(name string) (*corev1.Secret, error) { + if name == secret && namespace == namespace { + return &corev1.Secret{ + Data: map[string][]byte{ + key: []byte(cert), + }}, nil + } + return nil, errors.New("unexpected secret name or namespace passed to FakeSecretLister") + } + }) + } + }) + } tests := map[string]testNewConfigT{ "no CA bundle set in issuer should return nil": { issuer: gen.Issuer("vault-issuer", @@ -908,7 +928,7 @@ func TestNewConfig(t *testing.T) { }), ), expectedErr: nil, - checkFunc: func(cfg *vault.Config) error { + checkFunc: func(cfg *vault.Config, error error) error { testCA := x509.NewCertPool() testCA.AppendCertsFromPEM([]byte(testLeafCertificate)) subs := cfg.HttpClient.Transport.(*http.Transport).TLSClientConfig.RootCAs.Subjects() @@ -927,26 +947,107 @@ func TestNewConfig(t *testing.T) { return nil }, }, + + "a good bundle from a caBundleSecretRef should be added to the config": { + issuer: gen.Issuer("vault-issuer", + gen.SetIssuerVault(cmapi.VaultIssuer{ + CABundleSecretRef: &cmmeta.SecretKeySelector{ + Key: "my-bundle.crt", + LocalObjectReference: cmmeta.LocalObjectReference{ + Name: "bundle", + }, + }, + }, + )), + checkFunc: func(cfg *vault.Config, error error) error { + if error != nil { + return error + } + + testCA := x509.NewCertPool() + testCA.AppendCertsFromPEM([]byte(testLeafCertificate)) + subs := cfg.HttpClient.Transport.(*http.Transport).TLSClientConfig.RootCAs.Subjects() + + err := fmt.Errorf("got unexpected root CAs in config, exp=%s got=%s", + testCA.Subjects(), subs) + if len(subs) != len(testCA.Subjects()) { + return err + } + for i := range subs { + if !bytes.Equal(subs[i], testCA.Subjects()[i]) { + return err + } + } + + return nil + }, + fakeLister: caBundleSecretRefFakeSecretLister("test-namespace", "bundle", "my-bundle.crt", testLeafCertificate), + }, + "a good bundle from a caBundleSecretRef with default key should be added to the config": { + issuer: gen.Issuer("vault-issuer", + gen.SetIssuerVault(cmapi.VaultIssuer{ + CABundleSecretRef: &cmmeta.SecretKeySelector{ + LocalObjectReference: cmmeta.LocalObjectReference{ + Name: "bundle", + }, + }, + }, + )), + checkFunc: func(cfg *vault.Config, error error) error { + if error != nil { + return error + } + + testCA := x509.NewCertPool() + testCA.AppendCertsFromPEM([]byte(testLeafCertificate)) + subs := cfg.HttpClient.Transport.(*http.Transport).TLSClientConfig.RootCAs.Subjects() + + err := fmt.Errorf("got unexpected root CAs in config, exp=%s got=%s", + testCA.Subjects(), subs) + if len(subs) != len(testCA.Subjects()) { + return err + } + for i := range subs { + if !bytes.Equal(subs[i], testCA.Subjects()[i]) { + return err + } + } + + return nil + }, + fakeLister: caBundleSecretRefFakeSecretLister("test-namespace", "bundle", "ca.crt", testLeafCertificate), + }, + "a bad bundle from a caBundleSecretRef should error": { + issuer: gen.Issuer("vault-issuer", + gen.SetIssuerVault(cmapi.VaultIssuer{ + CABundleSecretRef: &cmmeta.SecretKeySelector{ + Key: "my-bundle.crt", + LocalObjectReference: cmmeta.LocalObjectReference{ + Name: "bundle", + }, + }, + }, + )), + expectedErr: errors.New("error loading Vault CA bundle"), + fakeLister: caBundleSecretRefFakeSecretLister("test-namespace", "bundle", "my-bundle.crt", "not a valid certificate"), + }, } for name, test := range tests { t.Run(name, func(t *testing.T) { v := &Vault{ namespace: "test-namespace", - secretsLister: nil, + secretsLister: test.fakeLister, issuer: test.issuer, } cfg, err := v.newConfig() - if ((test.expectedErr == nil) != (err == nil)) && - test.expectedErr != nil && - test.expectedErr.Error() != err.Error() { - t.Errorf("unexpected error, exp=%v got=%v", - test.expectedErr, err) + if test.expectedErr != nil && err != nil && test.expectedErr.Error() != err.Error() { + t.Errorf("unexpected error, exp=%v got=%v", test.expectedErr, err) } if test.checkFunc != nil { - if err := test.checkFunc(cfg); err != nil { + if err := test.checkFunc(cfg, err); err != nil { t.Errorf("check function failed: %s", err) } } diff --git a/pkg/apis/certmanager/v1/types_issuer.go b/pkg/apis/certmanager/v1/types_issuer.go index 9996bf1dc..363d66920 100644 --- a/pkg/apis/certmanager/v1/types_issuer.go +++ b/pkg/apis/certmanager/v1/types_issuer.go @@ -207,28 +207,18 @@ type VaultIssuer struct { // certificate. Only used if the Server URL is using HTTPS protocol. This // parameter is ignored for plain HTTP protocol connection. If not set the // system root certificates are used to validate the TLS connection. + // Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, + // the cert-manager controller system root certificates are used to validate the TLS connection. // +optional CABundle []byte `json:"caBundle,omitempty"` - // Like CABundle but loads the CA bundle from a Kubernetes Secret. - // CABundle will take precedence if also set. + // CABundleSecretRef is a reference to a Secret which contains the CABundle which will be used when + // connecting to Vault when using HTTPS. + // Mutually exclusive with CABundle. If neither CABundleSecretRef nor CABundle are defined, the cert-manager + // controller system root certificates are used to validate the TLS connection. + // If no key for the Secret is specified, cert-manager will default to 'ca.crt'. // +optional - CABundleSecretRef VaultCaBundleSecretRef `json:"caBundleSecretRef,omitempty"` -} - -type VaultCaBundleSecretRef struct { - // The name of the Secret resource being referred to. - Name string `json:"name"` - - // The namespace of the Secret resource being referred to. - // If omitted, it will use the namespace of the referent. If the referent - // is a cluster-scoped resource (e.g. a ClusterIssuer), the namespace of - // the configured 'cluster resource namespace' will be used. It is set as a - // flag on the controller component (and defaults to the namespace that cert-manager runs in). - Namespace string `json:"namespace,omitempty""` - - // The key of the entry in the Secret resource's `data` field to be used. - Key string `json:"key"` + CABundleSecretRef *cmmeta.SecretKeySelector `json:"caBundleSecretRef,omitempty"` } // Configuration used to authenticate with a Vault server. diff --git a/pkg/apis/certmanager/v1/zz_generated.deepcopy.go b/pkg/apis/certmanager/v1/zz_generated.deepcopy.go index 1f86572fd..3a9f68f80 100644 --- a/pkg/apis/certmanager/v1/zz_generated.deepcopy.go +++ b/pkg/apis/certmanager/v1/zz_generated.deepcopy.go @@ -865,22 +865,6 @@ func (in *VaultAuth) DeepCopy() *VaultAuth { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VaultCaBundleSecretRef) DeepCopyInto(out *VaultCaBundleSecretRef) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultCaBundleSecretRef. -func (in *VaultCaBundleSecretRef) DeepCopy() *VaultCaBundleSecretRef { - if in == nil { - return nil - } - out := new(VaultCaBundleSecretRef) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = *in @@ -890,7 +874,11 @@ func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) { *out = make([]byte, len(*in)) copy(*out, *in) } - out.CABundleSecretRef = in.CABundleSecretRef + if in.CABundleSecretRef != nil { + in, out := &in.CABundleSecretRef, &out.CABundleSecretRef + *out = new(apismetav1.SecretKeySelector) + **out = **in + } return } diff --git a/test/e2e/suite/issuers/vault/issuer.go b/test/e2e/suite/issuers/vault/issuer.go index e3f76a5a9..d3dd8559c 100644 --- a/test/e2e/suite/issuers/vault/issuer.go +++ b/test/e2e/suite/issuers/vault/issuer.go @@ -221,6 +221,20 @@ var _ = framework.CertManagerDescribe("Vault Issuer", func() { Expect(err).NotTo(HaveOccurred()) }) + It("should fail to init when both caBundle and caBundleSecretRef are set", func() { + By("Creating an Issuer") + vaultIssuer := gen.Issuer(issuerName, + gen.SetIssuerNamespace(f.Namespace.Name), + gen.SetIssuerVaultURL(vault.Details().Host), + gen.SetIssuerVaultPath(vaultPath), + gen.SetIssuerVaultCABundle(vault.Details().VaultCA), + gen.SetIssuerVaultCABundleSecretRef("ca-bundle", f.Namespace.Name, "ca.crt")) + _, err := f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name).Create(context.TODO(), vaultIssuer, metav1.CreateOptions{}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("spec.vault.caBundle: Invalid value: \"\": Specified caBundle and caBundleSecretRef cannot be used together")) + Expect(err.Error()).To(ContainSubstring("spec.vault.caBundleSecretRef: Invalid value: \"\": Specified caBundleSecretRef and caBundle cannot be used together")) + }) + It("should be ready with a caBundle from a Kubernetes Secret", func() { _, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Create(context.TODO(), vaultaddon.NewVaultKubernetesSecret(vaultSecretServiceAccount, vaultSecretServiceAccount), metav1.CreateOptions{}) Expect(err).NotTo(HaveOccurred()) @@ -255,31 +269,39 @@ var _ = framework.CertManagerDescribe("Vault Issuer", func() { Expect(err).NotTo(HaveOccurred()) }) - It("should be ready with a valid caBundle and an invalid caBundle from a Kubernetes Secret", func() { + It("should be eventually ready when the CA bundle secret gets created after the Issuer", func() { _, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Create(context.TODO(), vaultaddon.NewVaultKubernetesSecret(vaultSecretServiceAccount, vaultSecretServiceAccount), metav1.CreateOptions{}) Expect(err).NotTo(HaveOccurred()) + vaultIssuer := gen.Issuer(issuerName, + gen.SetIssuerNamespace(f.Namespace.Name), + gen.SetIssuerVaultURL(vault.Details().Host), + gen.SetIssuerVaultPath(vaultPath), + gen.SetIssuerVaultCABundleSecretRef("ca-bundle", f.Namespace.Name, "ca.crt"), + gen.SetIssuerVaultKubernetesAuth("token", vaultSecretServiceAccount, vaultKubernetesRoleName, kubernetesAuthPath)) + _, err = f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name).Create(context.TODO(), vaultIssuer, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Validate that the Issuer is not ready yet") + err = util.WaitForIssuerCondition(f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name), + issuerName, + v1.IssuerCondition{ + Type: v1.IssuerConditionReady, + Status: cmmeta.ConditionFalse, + }) + Expect(err).NotTo(HaveOccurred()) + _, err = f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Create(context.TODO(), &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "ca-bundle", }, Type: "Opaque", Data: map[string][]byte{ - "ca.crt": []byte("invalid CA cert"), + "ca.crt": vault.Details().VaultCA, }, }, metav1.CreateOptions{}) Expect(err).NotTo(HaveOccurred()) - vaultIssuer := gen.Issuer(issuerName, - gen.SetIssuerNamespace(f.Namespace.Name), - gen.SetIssuerVaultURL(vault.Details().Host), - gen.SetIssuerVaultPath(vaultPath), - gen.SetIssuerVaultCABundle(vault.Details().VaultCA), - gen.SetIssuerVaultCABundleSecretRef("ca-bundle", f.Namespace.Name, "ca.crt"), - gen.SetIssuerVaultKubernetesAuth("token", vaultSecretServiceAccount, vaultKubernetesRoleName, kubernetesAuthPath)) - _, err = f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name).Create(context.TODO(), vaultIssuer, metav1.CreateOptions{}) - Expect(err).NotTo(HaveOccurred()) - By("Waiting for Issuer to become Ready") err = util.WaitForIssuerCondition(f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name), issuerName, diff --git a/test/unit/gen/issuer.go b/test/unit/gen/issuer.go index e844dcb02..1d2ca4197 100644 --- a/test/unit/gen/issuer.go +++ b/test/unit/gen/issuer.go @@ -283,10 +283,11 @@ func SetIssuerVaultCABundleSecretRef(name, namespace, key string) IssuerModifier if spec.Vault == nil { spec.Vault = &v1.VaultIssuer{} } - spec.Vault.CABundleSecretRef = v1.VaultCaBundleSecretRef{ - Name: name, - Namespace: namespace, - Key: key, + spec.Vault.CABundleSecretRef = &cmmeta.SecretKeySelector{ + LocalObjectReference: cmmeta.LocalObjectReference{ + Name: name, + }, + Key: key, } } }