-
Notifications
You must be signed in to change notification settings - Fork 1.2k
restructure certwriter and certprovisioner packages #113
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
restructure certwriter and certprovisioner packages #113
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review is still in progress. Have only reviewed till cert/doc.go
.
I was wondering if there is a way to split this review. Long reviews are really discouraging for the reviewers :)
pkg/webhook/bootstrap.go
Outdated
s.CertDir = path.Join("k8s-webhook-server", "cert") | ||
} | ||
if s.KVMap == nil { | ||
s.KVMap = map[string]interface{}{} | ||
} | ||
s.setBootstrappingDefault() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
almost missed this because simply assumed all stuff is being defaulted inline here (no func call).
May be from readability perspective, we can group the inline defaults above in separate method and invoke the method here ?
@@ -54,7 +56,10 @@ func (s *Server) setDefault() { | |||
s.Port = 443 | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the defaults for s.Host
and s.Service
should be moved here from the setBootstrappingDefault
method ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s.Host and s.Service is for bootstrapping the AdmissionWebhookConfiguration and Service.
pkg/webhook/bootstrap.go
Outdated
s.CertGenerator = &generator.SelfSignedCertGenerator{} | ||
} | ||
if s.Writer == nil { | ||
s.Writer = os.Stdout | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused about what belongs to boostrapping
and what belongs at the server level ? Looking at the attributes looks like all of them can be done inline in the setDefaults
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually they were in the same defaulting function and I didn't plan to distinguish them. But the linter keeps complaining about high cyclomatic complexity. Then I have to split this defauting function :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.
pkg/webhook/bootstrap.go
Outdated
// Provision the cert by creating new one or refreshing existing one. | ||
s.certProvisioner.Provision(false) | ||
// Inject the cert into MutatingWebhookConfiguration, ValidatingWebhookConfiguration and ConversionWebhook | ||
s.certProvisioner.Inject(s.mutatingWebhookConfig, s.validatingWebhookConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-reading the code, I have a few naming suggestion for Inject
:
ApplyConfig
?
ConfigureWebhook
?
Configure
?
So it will read like:
Provision the certs and then the configure or apply the config for webhooks.
pkg/webhook/bootstrap.go
Outdated
cc, err := s.clientConfig() | ||
|
||
s.certProvisioner = &cert.Provisioner{ | ||
ClientConfig: cc, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering if this should be a parameter to the Inject
method ?
Do we envision certProvisioner's Inject
being called with different configs
? (by other programs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do that, then certProvisioner
and certWrtier
initialization can be moved to setDefault
probably ? and bootstrap just becomes:
- Generate the configuration
- Apply the configuration
pkg/webhook/bootstrap.go
Outdated
// TODO: use the helper in #98 when it merges. | ||
func createOrReplace(c client.Client, obj runtime.Object, fn mutateFn) error { | ||
func createOrReplaceHelper(c client.Client, obj runtime.Object, fn mutateFn) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm....looks like this could be useful in general. We might be able to move these under controller-runtime
under some clientutil
pkg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be a temporary thing.
#98 will land sometime.
pkg/webhook/bootstrap.go
Outdated
func (w *webhookClientConfig) withPath(path string) error { | ||
if w.URL != nil { | ||
u, err := url.Parse(*w.URL) | ||
func (s *Server) clientConfigWithPath(path string) (*admissionregistration.WebhookClientConfig, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment explaining path
will be helpful here.
} | ||
|
||
if len(mutatingWebhooks) > 0 { | ||
return &admissionregistration.MutatingWebhookConfiguration{ | ||
TypeMeta: metav1.TypeMeta{ | ||
APIVersion: "admissionregistration.k8s.io/v1beta1", | ||
APIVersion: fmt.Sprintf("%s/%s", admissionregistration.GroupName, "v1beta1"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think http
pkg has some utility methods to manipulate the URL paths, would suggest using those.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... Why handling apiVersion with URL manipulation util in http pkg?
if w.Service != nil { | ||
w.Service.Path = &path | ||
if cc.Service != nil { | ||
cc.Service.Path = &path | ||
} | ||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm..... may be we need ccWithPath type
with methods it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made some changes here.
pkg/webhook/cert/doc.go
Outdated
Build the Provisioner | ||
provisioner := Provisioner{ | ||
CertWriter: admission.NewSecretCertWriter(admission.SecretCertWriterOptions{...}), | ||
ClientConfig: cc, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I commented earlier if we can make it a parameter to the Inject
method ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took another look, have some more comments.
pkg/webhook/server.go
Outdated
return s.bootstrap(true) | ||
} | ||
|
||
// RefreshCert refreshes the certificate using Server's Provisioner if the certificate is expiring. | ||
func (s *Server) RefreshCert() error { | ||
func (s *Server) RefreshCert() (bool, error) { | ||
objs := []runtime.Object{s.mutatingWebhookConfig, s.validatingWebhookConfig} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can have a method s.webhookConfigTarget()
or s.webhookConfigObjects()
(I am seeing this in multiple places) ?
err = s.RefreshCert() | ||
if !changed { | ||
continue | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should add a log statement indicating server is shutting down to refresh the certs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
pkg/webhook/server.go
Outdated
@@ -189,21 +200,27 @@ func (s *Server) Start(stop <-chan struct{}) error { | |||
errCh <- err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering where writer
is coming from ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
writer
is package name here.
pkg/webhook/server.go
Outdated
sMux: http.NewServeMux(), | ||
registry: map[string]Webhook{}, | ||
ServerOptions: ops, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ops --> options
ops reads as operations :)
pkg/webhook/cert/provisioner.go
Outdated
// Provision provisions certificates for for the WebhookClientConfig. | ||
// It ensures the cert and CA are valid and not expiring. | ||
// It updates the CABundle in the webhookClientConfig if necessary. | ||
func (cp *Provisioner) Provision(dryrun bool) (bool, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if we should combine Provision
and Inject
methods into one by introducing parameters to Provision
method because ideally, that should be one operation. provision and inject cc in the objects ?
pkg/webhook/cert/provisioner.go
Outdated
} | ||
} | ||
return cp.CertWriter.Inject(objs...) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do I ensure that caller have called Provision
before Inject
? or is it okay ?
pkg/webhook/server.go
Outdated
@@ -84,9 +89,15 @@ type BootstrapOptions struct { | |||
// If neither Service nor Host is unspecified, Host will be defaulted to "localhost". | |||
Host *string | |||
|
|||
// Provisioner provisions certificates for the admission webhook server. | |||
// fid godoc Provisioner provisions certificates for the admission webhook server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: fid godoc
pkg/webhook/bootstrap.go
Outdated
s.CertGenerator = &generator.SelfSignedCertGenerator{} | ||
} | ||
if s.Writer == nil { | ||
s.Writer = os.Stdout | ||
} | ||
} | ||
|
||
// bootstrap returns the configuration of admissionWebhookConfiguration in yaml format if dryrun is true. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment hasn't been updated.
pkg/webhook/bootstrap.go
Outdated
if err != nil { | ||
return nil, err | ||
|
||
cc, err := s.clientConfig() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you can have another function like getConfigs
to get all the configs needed in bootstrap: mutatinWebhookConfig
, validatingWHConfig
and clientConfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clientConfig
is not a runtime.Object
. It's a field in both mutatinWebhookConfig and validatingWHConfig.
pkg/webhook/bootstrap.go
Outdated
@@ -353,11 +381,11 @@ func (s *Server) admissionWebhook(path string, wh *admission.Webhook) (*admissio | |||
if err != nil { | |||
return nil, err | |||
} | |||
err = cc.withPath(path) | |||
err = setPath(cc, path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you using clientConfigWithPath
instead of clientConfig
and setPath
?
pkg/webhook/cert/writer/fs.go
Outdated
// certGenerator generates the certificates. | ||
certGenerator generator.CertGenerator | ||
// path is the directory that the certificate and private key and CA certificate will be written. | ||
path string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use FSCertWriterOptions
instead of path and certGenerator? It has better readability
8395cd6
to
2b2a4ee
Compare
Addressed comments and rebased on #115. PTAL |
Travis is failing due to an linter error. EDIT: |
2b2a4ee
to
e3ce169
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
pkg/webhook/bootstrap.go
Outdated
s.CertGenerator = &generator.SelfSignedCertGenerator{} | ||
} | ||
if s.Writer == nil { | ||
s.Writer = os.Stdout | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.
pkg/webhook/bootstrap.go
Outdated
// Otherwise, it creates the the admissionWebhookConfiguration objects and service if any. | ||
// It also provisions the certificate for your admission server. | ||
// It also provisions the certificate for the admission server. | ||
func (s *Server) bootstrap(dryrun bool) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be we should rename this function to installWebhookConfig
to make it more explicit. Also, can dryrun
be a server option ?
once sync.Once | ||
// Objects are the objects that will use the ClientConfig above. | ||
Objects []runtime.Object | ||
// Dryrun controls if the objects are sent to the API server or output in the io.Writer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/output in/written to
0e45f79
to
2f1180d
Compare
Rebased on #123 |
2f1180d
to
7fdb8b1
Compare
Cherry-picked #126 |
Looks good to me. You can squash the commits, then we can merge it. |
7fdb8b1
to
617592c
Compare
@droot Done |
617592c
to
f297678
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED Approval requirements bypassed by manually added approval. This pull-request has been approved by: mengqiy 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 |
Add basic test for kubebuilder create config --crds
This PR is ready for 1st round review.
Will add the tests very soon.
godoc:
http://35.232.176.188/pkg/sigs.k8s.io/controller-runtime/pkg/webhook/