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

Webhook enhancements #543

Merged
merged 16 commits into from
Aug 15, 2019
Merged

Conversation

khogeland
Copy link
Contributor

Bundled to avoid merge conflicts

Subsumes #515 #516 #517:

  • Periodic cert reloading
  • Improved error reporting
  • Strict error handling

}

func (c *certProvider) Start() {
stopChannel := make(chan interface{})
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like you can initialize this field in NewCertProvider, and then use case <-c.stopChannel below. Ditto for ticker.

if userConfig.webhookNamespaceSelector == "" {
glog.Fatal("webhook-namespace-selector must be set when webhook-fail-on-error is true.")
} else {
kv := strings.SplitN(userConfig.webhookNamespaceSelector, "=", 2)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should also support specification of multiple selector entries, e.g., key1=val1,key2=val2.

func (c *certProvider) tlsConfig() *tls.Config {
return &tls.Config{
GetCertificate: func(ch *tls.ClientHelloInfo) (*tls.Certificate, error) {
return c.currentCert, nil
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need to use a mutex to guard currentCert, which may be read in tlsConfig and written in updateCert?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's probably a good idea, since this behavior is technically undefined (although AFAICT it's safe on all modern architectures).

}
if userConfig.webhookFailOnError {
if userConfig.webhookNamespaceSelector == "" {
glog.Fatal("webhook-namespace-selector must be set when webhook-fail-on-error is true.")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remind me why is this a requirement?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because the operator going down would cause a cluster-wide outage. And if the operator pod were rescheduled, it would required manual intervention (because it would have a circular dependency on itself to start up).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Got it. Instead of using glog.Fatal, please return an error instead. The caller of New will do glog.Fatal on the return error anyway.

@liyinan926
Copy link
Collaborator

@khogeland can you address the remaining comments? It looks good otherwise.

@khogeland
Copy link
Contributor Author

@liyinan926 Addressed your above comments

Copy link
Collaborator

@liyinan926 liyinan926 left a comment

Choose a reason for hiding this comment

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

LGTM overall. I will fix the minor issues later.

@@ -254,61 +348,47 @@ func (wh *WebHook) selfDeregistration(webhookConfigName string) error {
func mutatePods(
review *admissionv1beta1.AdmissionReview,
lister crdlisters.SparkApplicationLister,
sparkJobNs string) *admissionv1beta1.AdmissionResponse {
sparkJobNs string) (*admissionv1beta1.AdmissionResponse, error) {
if review.Request.Resource != podResource {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like we don't need this check here any more as the same check is added above.

w.WriteHeader(code)
_, err = w.Write(resp)
if err != nil {
glog.Errorf("Failed to write response body: %v", err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: lower case for error messages.

glog.Error(err)
reviewResponse = toAdmissionResponse(err)
internalError(w, err)
return
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: this else is no longer needed with the return above.

if userConfig.webhookFailOnError {
if userConfig.webhookNamespaceSelector == "" {
return nil, fmt.Errorf("webhook-namespace-selector must be set when webhook-fail-on-error is true.")
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: this else is no longer needed with the return above.

@liyinan926 liyinan926 merged commit 249860f into kubeflow:master Aug 15, 2019
akhurana001 pushed a commit to lyft/spark-on-k8s-operator that referenced this pull request May 5, 2020
* Cert configuration and reloading

* Add support for strict webhook error handling

* Improve webhook error handling

* Don't deregister the webhook when failure policy is strict

* standard error message capitalization

* have the webhook parse its own configuration from flags

* clean up cert provider code

* Add explanation for skipping deregistration

* Tests and fixes
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.

2 participants