Skip to content
This repository has been archived by the owner on Oct 22, 2021. It is now read-only.

Support ExtendedSecret certs signed by the Kube API Server #484

Merged
merged 6 commits into from
Aug 19, 2019
Merged

Conversation

edwardstudy
Copy link
Member

@edwardstudy edwardstudy commented Aug 7, 2019

#167555390

  • Added two options to support CSR for ExtendedSecret:
SignerType       SignerType        `json:"signerType,omitempty"`
Usages           []certv1.KeyUsage `json:"usages,omitempty"`
  • Added CSR controller to watch CSR and approve it and then persists certificate signed by Kube API Server

Verification steps:

$ k apply -f ./docs/examples/extended-secret/certificate.yaml

$ k get secret
NAME                                   TYPE                                  DATA   AGE
...
nats-deployment.var-nats-cert    # This cert signed by API Server

@cfdreddbot
Copy link

✅ Hey edwardstudy! The commit authors and yourself have already signed the CLA.

pkg/kube/apis/extendedsecret/v1alpha1/types.go Outdated Show resolved Hide resolved
return reconcile.Result{}, nil
}

err = r.approveRequest(ctx, instance.Name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should better go into an else branch.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And couldn't we pass the object directly instead of its name to get rid of another get request?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it's helpful for reducing update conflicts.
And r.client could not update subresource approval. we have to use client-go.client to update CSR approval directly:
kubernetes-sigs/controller-runtime#172

@@ -180,6 +180,11 @@ func OrdinalFromPodName(name string) int {
return podOrdinal
}

// PrivateKeySecretName returns a Secret name for a given ExtendedSecret
func PrivateKeySecretName(extendedSecretName string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this name a bit more precise, i.e. CsrPrivateKeySecretName?

}

if len(instance.Status.Certificate) != 0 {
annotations := instance.GetAnnotations()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just wondering, why do we need these annotations? Couldn't we get the secret name and namespace from the owner object (ExtendedSecret)?

Copy link
Member Author

@edwardstudy edwardstudy Aug 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The truth is that:

  1. CSR is no-namespaced
  2. the owner and owned object are both namespace-scoped and assumed in the same namespace

kubernetes-sigs/controller-runtime#214 (comment)

So getting the owner's namespace from CSR could not get right namespace.
My idea is to set the owner's namespace to annotations.

@@ -124,6 +127,7 @@ func (r *ReconcileExtendedSecret) Reconcile(request reconcile.Request) (reconcil
func (r *ReconcileExtendedSecret) updateExSecret(ctx context.Context, instance *esv1.ExtendedSecret) error {
obj := instance.DeepCopy()
op, err := controllerutil.CreateOrUpdate(ctx, r.client, obj, func() error {
obj.Spec = instance.Spec
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's helpful to update default spec.request.signerType if it's certificate.

Copy link
Member Author

@edwardstudy edwardstudy Aug 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactored CreateOrUpdate mutateFn. As I said, empty spec.request.signerType would be populated as local.

- '*.foo.com'
commonName: routerSSL
isCA: false
signerType: external
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it's not using the API server to sign

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed CA infos. Sorry for misleading example.

docs/controllers/extendedsecret.md Outdated Show resolved Hide resolved
@edwardstudy
Copy link
Member Author

edwardstudy commented Aug 16, 2019

cf-operator can consume following CR and create cert signed by API server now:

---
apiVersion: fissile.cloudfoundry.org/v1alpha1
kind: ExtendedSecret
metadata:
  name: generate-certificate
spec:
  request:
    certificate:
      alternativeNames:
        - foo.com
        - '*.foo.com'
      commonName: routerSSL
      signerType: cluster
      usages: ["server auth", "client auth"]
  secretName: gen-certificate
  type: certificate

Copy link
Contributor

@aduffeck aduffeck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm besides the test expectation change

e2e/kube/examples_test.go Show resolved Hide resolved
@aduffeck aduffeck merged commit e18fa78 into master Aug 19, 2019
@aduffeck aduffeck deleted the ed/csr branch August 19, 2019 08:19
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants