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

Extensible Certificate Issuing Controller #2782

Merged

Conversation

JoshVanL
Copy link
Collaborator

@JoshVanL JoshVanL commented Apr 5, 2020

/cc @munnerz

This controller is used to implement the issuing controller, as described in the extensible certificates controller proposal here #2753. This controller is responsible for writing the resulting certificate, ca, and private key to the target certificate resource, in the correct fromat.

Adds new extensible issuing certificate

@jetstack-bot jetstack-bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. dco-signoff: yes Indicates that all commits in the pull request have the valid DCO sign-off message. area/api Indicates a PR directly modifies the 'pkg/apis' directory labels Apr 5, 2020
@jetstack-bot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: JoshVanL

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@jetstack-bot jetstack-bot added area/deploy Indicates a PR modifies deployment configuration area/testing Issues relating to testing kind/design Categorizes issue or PR as related to design. approved Indicates a PR has been approved by an approver from all required OWNERS files. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Apr 5, 2020
@JoshVanL JoshVanL force-pushed the certificate-issuing-controller branch 2 times, most recently from 16f4634 to eb16d01 Compare April 5, 2020 19:40
@munnerz munnerz added this to the v0.15 milestone Apr 6, 2020

// Remove this condition from the condition slice
copy(crt.Status.Conditions[i:], crt.Status.Conditions[i+1:])
crt.Status.Conditions = crt.Status.Conditions[:len(crt.Status.Conditions)-1]
Copy link
Member

Choose a reason for hiding this comment

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

Looping over a slice while modifying it is a tricky one - the i will not be correct after one element is removed. Instead, accumulate a new conditions slice that contains everything except conditions of the given type. This means you don't need i at all 😄

@@ -249,6 +264,24 @@ func CertificateRequestReadyReason(cr *cmapi.CertificateRequest) string {
return ""
}

// This returns with the message if the CertificateRequest contains an
// Failed condition, and returns "" otherwise.
func CertificateRequestFailedMessage(cr *cmapi.CertificateRequest) string {
Copy link
Member

Choose a reason for hiding this comment

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

Hm, whilst we do have CertificateRequestReadyReason, this is because it is utilised at multiple places within the codebase and makes readability better. In this case, we're only really using it in one place (here: eb16d01#diff-528fa7c9a9cfce42c4813bd3207bb714R199)

Can we instead change this to be a call to GetCertificateRequestCondition, and then reference the appropriate within that accordingly? We can then remove this altogether 😄

@@ -55,6 +55,7 @@ const (
// Annotation names for CertificateRequests
const (
CRPrivateKeyAnnotationKey = "cert-manager.io/private-key-secret-name"
CRRevisionAnnotationKey = "cert-manager.io/revision"
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a comment? (and in v1alpha3 & internal)

Copy link
Member

Choose a reason for hiding this comment

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

pkg/controller/expcertificates/util.go already defines this annotation: CertificateRevisionAnnotationKey = "cert-manager.io/certificate-revision".

  1. can you change this to be certificate-revision instead (as per design doc)
  2. can you remove duplicate definitions? 😄

// secretData is a structure wrapping private key, certificate and CA data
type secretData struct {
sk, cert, ca []byte
}
Copy link
Member

Choose a reason for hiding this comment

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

nit: does this make more sense to define in secret.go?

// obtain references to all the informers used by this controller
certificateInformer := cmFactory.Certmanager().V1alpha2().Certificates()
certificateRequestInformer := cmFactory.Certmanager().V1alpha2().CertificateRequests()
secretsInformer := factory.Core().V1().Secrets()
Copy link
Member

Choose a reason for hiding this comment

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

Missing event handler watching Secret resources named as status.nextPrivateKeySecretName

return err
}

secretExists := true
Copy link
Member

Choose a reason for hiding this comment

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

nit: secretExists := (secret != nil) 🤷‍♂

if err != nil {
return err
}
if reflect.DeepEqual(secret, newSecret) {
Copy link
Member

Choose a reason for hiding this comment

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

This behaviour does make sense, although I wonder if it will 'hide' real errors in our code/state machine.. perhaps one to try and tackle later, but for now maybe add a comment and possibly a log message in case this case occurs? (maybe at DebugLevel..)

Copy link
Member

Choose a reason for hiding this comment

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

Hm, this check also won't work when P12/JKS support is enabled, as these formats use a random parameter when encrypting the keystore meaning the secretes will never be equal despite containing equal private keys/certs.

Given that, and given we don't have exhaustive testing around P12/JKS right now to identify how serious of an issue this is, an implementation that doesn't rely on this check would be best if possible!

// If secret does not exist then create it
if !secretExists {
_, err = c.kubeClient.CoreV1().Secrets(newSecret.Namespace).Create(secretCtx, newSecret, metav1.CreateOptions{})
if err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Replace with return err regardless of err != nil

return err
}

return nil
Copy link
Member

Choose a reason for hiding this comment

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

nit: return err and remove the above check

delete(s.Annotations, cmapi.IPSANAnnotationKey)
delete(s.Annotations, cmapi.URISANAnnotationKey)
} else {
x509Cert, err := utilpki.DecodeX509CertificateBytes(data.cert)
Copy link
Member

Choose a reason for hiding this comment

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

Just a note: this will be problematic in future once we begin natively support JKS and P12 as the DecodeX509CertificateBytes method will not be 'taught' how to decode these keystore formats (due to the complexity of manage encryption keys in this area of code).

Instead, we should be relying on the certificate data stored on the CertificateRequest and the private key data stored in the nextPrivateKeySecretName. Right now, in all cases, these are the same, so the code is safe.

But we're going to need to refactor all this a bit once we go to add P12 and JKS support 😄

Happy to merge without changes for now, but just a quick note! 😄

@munnerz
Copy link
Member

munnerz commented Apr 7, 2020

Some integration and unit tests to cover this controller would also be great 😄

@jetstack-bot jetstack-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 8, 2020
@JoshVanL JoshVanL force-pushed the certificate-issuing-controller branch 2 times, most recently from 689878c to 0ccd364 Compare April 12, 2020 23:52
@JoshVanL JoshVanL changed the title WIP: Extensible Certificate Issuing Controller Extensible Certificate Issuing Controller Apr 13, 2020
@jetstack-bot jetstack-bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 13, 2020
@JoshVanL
Copy link
Collaborator Author

@munnerz Should be good to have another look :)

/assign @munnerz

@munnerz munnerz force-pushed the certificate-issuing-controller branch from 2d375ee to 544b028 Compare April 15, 2020 14:54
@jetstack-bot jetstack-bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 15, 2020
Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
JoshVanL and others added 2 commits April 15, 2020 16:16
Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
Signed-off-by: James Munnelly <james@munnelly.eu>
@munnerz munnerz force-pushed the certificate-issuing-controller branch from 544b028 to 572e467 Compare April 15, 2020 15:28
Signed-off-by: James Munnelly <james@munnelly.eu>
@munnerz
Copy link
Member

munnerz commented Apr 16, 2020

I'm going to be following up with additional PRs around this (+ additional controllers) 😄

/lgtm

@jetstack-bot jetstack-bot added the lgtm Indicates that a PR is ready to be merged. label Apr 16, 2020
@jetstack-bot jetstack-bot merged commit f3df903 into cert-manager:master Apr 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/api Indicates a PR directly modifies the 'pkg/apis' directory area/deploy Indicates a PR modifies deployment configuration area/testing Issues relating to testing dco-signoff: yes Indicates that all commits in the pull request have the valid DCO sign-off message. kind/design Categorizes issue or PR as related to design. lgtm Indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants