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

pkg/certs: Move certgen into a public package so other projects can consume #3135

Merged
merged 7 commits into from
Jan 13, 2021

Conversation

stevesloka
Copy link
Member

Some projects like the Contour Operator, need ways to create certificates for
Contour deployments. Currently, this is done via a Kubernetes Job which executes
the Contour command certgen which generates self-signed certificates used for
communication between Contour<>Envoy.

This moves the generation logic into a public package (e.g. pkg/certs) which
allows projects to consume this same code to generate certificates by other
means other than the Contour certgen command.

Fixes #3130

Signed-off-by: Steve Sloka slokas@vmware.com

@stevesloka stevesloka added this to the 1.11.0 milestone Nov 17, 2020
@stevesloka
Copy link
Member Author

@codecov
Copy link

codecov bot commented Nov 17, 2020

Codecov Report

Merging #3135 (cc2c5f2) into main (ca29391) will decrease coverage by 0.08%.
The diff coverage is 69.56%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3135      +/-   ##
==========================================
- Coverage   75.39%   75.30%   -0.09%     
==========================================
  Files          97       96       -1     
  Lines        6023     5925      -98     
==========================================
- Hits         4541     4462      -79     
+ Misses       1372     1363       -9     
+ Partials      110      100      -10     
Impacted Files Coverage Δ
cmd/contour/certgen.go 26.00% <0.00%> (-21.30%) ⬇️
internal/certgen/certgen.go 72.83% <100.00%> (ø)
internal/dag/httpproxy_processor.go 94.15% <0.00%> (-0.02%) ⬇️
internal/k8s/log.go 69.56% <0.00%> (+6.52%) ⬆️

pkg/certs/certgen.go Outdated Show resolved Hide resolved
}

// GenerateCerts performs the actual cert generation steps and then returns the certs for the output function.
func GenerateCerts(certConfig *CertgenConfig) (map[string][]byte, error) {
Copy link
Member

Choose a reason for hiding this comment

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

any reason not to combine GenerateCerts and OutputCerts into a single exported function, since they need to be called one after the other? It'd make for a slightly cleaner public API IMHO.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I'll do that, less API exposed is better. =)

Copy link
Member Author

Choose a reason for hiding this comment

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

In looking into this a bit more, it seems like we should have 3 public methods outlined below. The confusing part about how it's built today is that if you request a cert in yaml or pem format, you still need to pass a kubeclient which isn't used at all in those two situations.

  1. Kubernetes Secret (--kube), GenerateKubeCertificates(format string, kubeclient *kubernetes.Clientset, overwrite bool)
  2. Yaml (--yaml), GenerateYamlCertificates(format, outputDirectory string, force bool)
  3. PEM (--pem), GeneratePemCertificates(format, outputDirectory string, force bool)

Note: We could combine the yaml & pem into a single one, but I'd probably keep separate? /shrug

This means then that the doCertgen() inside cmd/contour will look at the flags passed and call each public method appropriately, but external callers have a clean API to use to code against.

Copy link
Contributor

Choose a reason for hiding this comment

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

I propose just one API:

type CertificateSet struct {
    Contour []byte
    Envoy []byte
    CA []byte
}

func GenerateCertificates(options ...) (CertificateSet, error)

The caller can deal with emitting the certificates in the way they need (i.e. contour-operator probably can't directly use any of the specific APIs above). We probably need the options so the caller can do things like set unique SAN entries.

Copy link
Member Author

Choose a reason for hiding this comment

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

The operator can use the apis above as-is.

The work to serialize them to pem or yaml or secrets is a benefit of using a library as this is intended so the caller doesn't need to reinvent that work.

Copy link
Member Author

Choose a reason for hiding this comment

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

There could be further customizations to add name, etc, etc, but could come as well as needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

The operator can use the apis above as-is.

Are you sure? The operator doesn't need GenerateYamlCertificates or GenerateYamlCertificates. It may need GenerateKubeCertificates, but (1) depending on the Kubernetes framework it uses, it may not have easy access to the right client struct (2) it may need to specify the name or namespace of the secret (3) it may need to set owner references or other object meta information (4) it may combine the certificates into secrets in way this function does not anticipate.

Copy link
Member Author

Choose a reason for hiding this comment

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

Requirements / needs will change over time, 💯 .

Copy link
Member

Choose a reason for hiding this comment

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

I like the sound of @jpeach's suggestion, it seems like a nice, clean API. I think it's probably better to have separate Output functions for each type though, so that we can ensure that things consuming this package output their certs in the right way (ie files have the correct permissions etc, certificates are in the right formats, and so on). Callers don't have to use the Output functions, but supplying them makes keeping things in sync easier.

@skriss skriss modified the milestones: 1.11.0, 1.12.0 Dec 17, 2020
@github-actions
Copy link

github-actions bot commented Jan 1, 2021

Marking this PR stale since there has been no activity for 14 days. It will be closed if there is no activity for another 90 days.

@github-actions github-actions bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jan 1, 2021
@stevesloka stevesloka removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jan 5, 2021
@stevesloka
Copy link
Member Author

Ok folks, I just did a big refactor to this, please take a look.

pkg/certs/certgen.go Outdated Show resolved Hide resolved
…onsume

Some projects like the Contour Operator, need ways to create certificates for
Contour deployments. Currently, this is done via a Kubernetes Job which executes
the Contour command `certgen` which generates self-signed certificates used for
communication between Contour<>Envoy.

This moves the generation logic into a public package (e.g. pkg/certs) which
allows projects to consume this same code to generate certificates by other
means other than the Contour `certgen` command.

Fixes projectcontour#3130

Signed-off-by: Steve Sloka <slokas@vmware.com>
Signed-off-by: Steve Sloka <slokas@vmware.com>
Copy link
Member

@sunjayBhatia sunjayBhatia left a comment

Choose a reason for hiding this comment

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

LGTM, looks like a solid move over of the existing code and kept to the pared down interface, with some configurability

Copy link
Member

@skriss skriss left a comment

Choose a reason for hiding this comment

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

It'd be great to get @danehans to take a look at this too and validate that the public API will work for the operator's needs.

pkg/certs/certgen.go Outdated Show resolved Hide resolved
pkg/certs/certgen.go Outdated Show resolved Hide resolved
pkg/certs/certgen.go Outdated Show resolved Hide resolved
pkg/certs/certgen.go Outdated Show resolved Hide resolved
@skriss skriss requested a review from danehans January 5, 2021 19:46
pkg/certs/certgen.go Outdated Show resolved Hide resolved
Signed-off-by: Steve Sloka <slokas@vmware.com>
@stevesloka stevesloka requested a review from a team as a code owner January 5, 2021 21:08
Signed-off-by: Steve Sloka <slokas@vmware.com>
Copy link
Member

@skriss skriss left a comment

Choose a reason for hiding this comment

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

LGTM assuming @danehans confirms this will meet the Operator's needs.

Copy link
Member

@youngnick youngnick left a comment

Choose a reason for hiding this comment

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

LGTM, nice work @stevesloka

@sunjayBhatia sunjayBhatia merged commit 1a7ae70 into projectcontour:main Jan 13, 2021
erwbgy pushed a commit to erwbgy/contour that referenced this pull request Jan 14, 2021
…onsume (projectcontour#3135)

Some projects like the Contour Operator, need ways to create certificates for
Contour deployments. Currently, this is done via a Kubernetes Job which executes
the Contour command `certgen` which generates self-signed certificates used for
communication between Contour<>Envoy.

This moves the generation logic into a public package (e.g. pkg/certs) which
allows projects to consume this same code to generate certificates by other
means other than the Contour `certgen` command.

Fixes projectcontour#3130
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extract certgen logic into public package
5 participants