diff --git a/api/v1beta1/stepclusterissuer_types.go b/api/v1beta1/stepclusterissuer_types.go index 1fbdb600..e4142a11 100644 --- a/api/v1beta1/stepclusterissuer_types.go +++ b/api/v1beta1/stepclusterissuer_types.go @@ -40,8 +40,7 @@ type StepClusterIssuerSpec struct { // CABundle is a base64 encoded TLS certificate used to verify connections // to the step certificates server. If not set the system root certificates // are used to validate the TLS connection. - // +optional - CABundle []byte `json:"caBundle,omitempty"` + CABundle []byte `json:"caBundle"` } // StepClusterIssuerStatus defines the observed state of StepClusterIssuer diff --git a/api/v1beta1/stepissuer_types.go b/api/v1beta1/stepissuer_types.go index 3760e9a4..80c3a907 100644 --- a/api/v1beta1/stepissuer_types.go +++ b/api/v1beta1/stepissuer_types.go @@ -40,8 +40,7 @@ type StepIssuerSpec struct { // CABundle is a base64 encoded TLS certificate used to verify connections // to the step certificates server. If not set the system root certificates // are used to validate the TLS connection. - // +optional - CABundle []byte `json:"caBundle,omitempty"` + CABundle []byte `json:"caBundle"` } // StepIssuerStatus defines the observed state of StepIssuer diff --git a/config/crd/bases/certmanager.step.sm_stepclusterissuers.yaml b/config/crd/bases/certmanager.step.sm_stepclusterissuers.yaml index 022c90f9..2d15b365 100644 --- a/config/crd/bases/certmanager.step.sm_stepclusterissuers.yaml +++ b/config/crd/bases/certmanager.step.sm_stepclusterissuers.yaml @@ -81,6 +81,7 @@ spec: description: URL is the base URL for the step certificates instance. type: string required: + - caBundle - provisioner - url type: object diff --git a/config/crd/bases/certmanager.step.sm_stepissuers.yaml b/config/crd/bases/certmanager.step.sm_stepissuers.yaml index d266a113..ae935197 100644 --- a/config/crd/bases/certmanager.step.sm_stepissuers.yaml +++ b/config/crd/bases/certmanager.step.sm_stepissuers.yaml @@ -76,6 +76,7 @@ spec: description: URL is the base URL for the step certificates instance. type: string required: + - caBundle - provisioner - url type: object diff --git a/controllers/stepclusterissuer_controller.go b/controllers/stepclusterissuer_controller.go index be284496..3faa16a8 100644 --- a/controllers/stepclusterissuer_controller.go +++ b/controllers/stepclusterissuer_controller.go @@ -87,7 +87,6 @@ func (r *StepClusterIssuerReconciler) Reconcile(ctx context.Context, req ctrl.Re } // Initialize and store the provisioner - //nolint:contextcheck // legacy p, err := provisioners.NewFromStepClusterIssuer(iss, password) if err != nil { log.Error(err, "failed to initialize provisioner") @@ -111,6 +110,8 @@ func validateStepClusterIssuerSpec(s api.StepClusterIssuerSpec) error { switch { case s.URL == "": return fmt.Errorf("spec.url cannot be empty") + case len(s.CABundle) == 0: + return fmt.Errorf("spec.caBundle cannot be empty") case s.Provisioner.Name == "": return fmt.Errorf("spec.provisioner.name cannot be empty") case s.Provisioner.KeyID == "": diff --git a/controllers/stepissuer_controller.go b/controllers/stepissuer_controller.go index 6a63c2b3..3d47bc82 100644 --- a/controllers/stepissuer_controller.go +++ b/controllers/stepissuer_controller.go @@ -87,7 +87,6 @@ func (r *StepIssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) } // Initialize and store the provisioner - //nolint:contextcheck // legacy p, err := provisioners.NewFromStepIssuer(iss, password) if err != nil { log.Error(err, "failed to initialize provisioner") @@ -111,6 +110,8 @@ func validateStepIssuerSpec(s api.StepIssuerSpec) error { switch { case s.URL == "": return fmt.Errorf("spec.url cannot be empty") + case len(s.CABundle) == 0: + return fmt.Errorf("spec.caBundle cannot be empty") case s.Provisioner.Name == "": return fmt.Errorf("spec.provisioner.name cannot be empty") case s.Provisioner.KeyID == "": diff --git a/provisioners/step.go b/provisioners/step.go index 5085a6e9..c49e5fcb 100644 --- a/provisioners/step.go +++ b/provisioners/step.go @@ -21,16 +21,17 @@ var collection = new(sync.Map) // requests using step certificates. type Step struct { name string + caBundle []byte provisioner *ca.Provisioner } // NewFromStepIssuer returns a new Step provisioner, configured with the information in the // given issuer. func NewFromStepIssuer(iss *api.StepIssuer, password []byte) (*Step, error) { - var options []ca.ClientOption - if len(iss.Spec.CABundle) > 0 { - options = append(options, ca.WithCABundle(iss.Spec.CABundle)) + options := []ca.ClientOption{ + ca.WithCABundle(iss.Spec.CABundle), } + provisioner, err := ca.NewProvisioner(iss.Spec.Provisioner.Name, iss.Spec.Provisioner.KeyID, iss.Spec.URL, password, options...) if err != nil { return nil, err @@ -38,26 +39,18 @@ func NewFromStepIssuer(iss *api.StepIssuer, password []byte) (*Step, error) { p := &Step{ name: iss.Name + "." + iss.Namespace, + caBundle: iss.Spec.CABundle, provisioner: provisioner, } - // Request identity certificate if required. - if version, err := provisioner.Version(); err == nil { - if version.RequireClientAuthentication { - if err := p.createIdentityCertificate(); err != nil { - return nil, err - } - } - } - return p, nil } func NewFromStepClusterIssuer(iss *api.StepClusterIssuer, password []byte) (*Step, error) { - var options []ca.ClientOption - if len(iss.Spec.CABundle) > 0 { - options = append(options, ca.WithCABundle(iss.Spec.CABundle)) + options := []ca.ClientOption{ + ca.WithCABundle(iss.Spec.CABundle), } + provisioner, err := ca.NewProvisioner(iss.Spec.Provisioner.Name, iss.Spec.Provisioner.KeyID, iss.Spec.URL, password, options...) if err != nil { return nil, err @@ -65,18 +58,10 @@ func NewFromStepClusterIssuer(iss *api.StepClusterIssuer, password []byte) (*Ste p := &Step{ name: iss.Name + "." + iss.Namespace, + caBundle: iss.Spec.CABundle, provisioner: provisioner, } - // Request identity certificate if required. - if version, err := provisioner.Version(); err == nil { - if version.RequireClientAuthentication { - if err := p.createIdentityCertificate(); err != nil { - return nil, err - } - } - } - return p, nil } @@ -95,45 +80,9 @@ func Store(namespacedName types.NamespacedName, provisioner *Step) { collection.Store(namespacedName, provisioner) } -func (s *Step) createIdentityCertificate() error { - csr, pk, err := ca.CreateCertificateRequest(s.name) - if err != nil { - return err - } - token, err := s.provisioner.Token(s.name) - if err != nil { - return err - } - resp, err := s.provisioner.Sign(&capi.SignRequest{ - CsrPEM: *csr, - OTT: token, - }) - if err != nil { - return err - } - tr, err := s.provisioner.Client.Transport(context.Background(), resp, pk) - if err != nil { - return err - } - s.provisioner.Client.SetTransport(tr) - return nil -} - // Sign sends the certificate requests to the Step CA and returns the signed // certificate. func (s *Step) Sign(_ context.Context, cr *certmanager.CertificateRequest) ([]byte, []byte, error) { - // Get root certificate(s) - roots, err := s.provisioner.Roots() - if err != nil { - return nil, nil, err - } - - // Encode root certificates - caPem, err := encodeX509(roots.Certificates...) - if err != nil { - return nil, nil, err - } - // decode and check certificate request csr, err := decodeCSR(cr.Spec.Request) if err != nil { @@ -180,7 +129,7 @@ func (s *Step) Sign(_ context.Context, cr *certmanager.CertificateRequest) ([]by if err != nil { return nil, nil, err } - return chainPem, caPem, nil + return chainPem, s.caBundle, nil } // decodeCSR decodes a certificate request in PEM format and returns the