Skip to content

Commit

Permalink
⚠️ move webhook self installer to CT as generator
Browse files Browse the repository at this point in the history
  • Loading branch information
Mengqi Yu committed Feb 4, 2019
1 parent 2027a41 commit b2ea9dc
Show file tree
Hide file tree
Showing 38 changed files with 341 additions and 4,875 deletions.
6 changes: 1 addition & 5 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 7 additions & 39 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@ import (
"flag"
"os"

admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apitypes "k8s.io/apimachinery/pkg/types"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/manager"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
"sigs.k8s.io/controller-runtime/pkg/source"
"sigs.k8s.io/controller-runtime/pkg/webhook"
Expand Down Expand Up @@ -81,52 +79,22 @@ func main() {

// Setup webhooks
entryLog.Info("setting up webhooks")
mutatingWebhook, err := builder.NewWebhookBuilder().
Name("mutating.k8s.io").
mutatingWebhook := builder.NewWebhookBuilder().
Path("/mutate-pods").
Mutating().
Operations(admissionregistrationv1beta1.Create, admissionregistrationv1beta1.Update).
WithManager(mgr).
ForType(&corev1.Pod{}).
Handlers(&podAnnotator{}).
Build()
if err != nil {
entryLog.Error(err, "unable to setup mutating webhook")
os.Exit(1)
}

validatingWebhook, err := builder.NewWebhookBuilder().
Name("validating.k8s.io").
validatingWebhook := builder.NewWebhookBuilder().
Path("/validate-pods").
Validating().
Operations(admissionregistrationv1beta1.Create, admissionregistrationv1beta1.Update).
WithManager(mgr).
ForType(&corev1.Pod{}).
Handlers(&podValidator{}).
Build()
if err != nil {
entryLog.Error(err, "unable to setup validating webhook")
os.Exit(1)
}

entryLog.Info("setting up webhook server")
as, err := webhook.NewServer("foo-admission-server", mgr, webhook.ServerOptions{
Port: 9876,
CertDir: "/tmp/cert",
DisableWebhookConfigInstaller: &disableWebhookConfigInstaller,
BootstrapOptions: &webhook.BootstrapOptions{
Secret: &apitypes.NamespacedName{
Namespace: "default",
Name: "foo-admission-server-secret",
},

Service: &webhook.Service{
Namespace: "default",
Name: "foo-admission-server-service",
// Selectors should select the pods that runs this webhook server.
Selectors: map[string]string{
"app": "foo-admission-server",
},
},
},
Port: 9876,
CertDir: "/tmp/cert",
})
if err != nil {
entryLog.Error(err, "unable to create a new webhook server")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,4 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package generator

import "fmt"

func ExampleServiceToCommonName() {
fmt.Println(ServiceToCommonName("myservicenamespace", "myservicename"))
// Output: myservicename.myservicenamespace.svc
}
package admission
105 changes: 105 additions & 0 deletions pkg/internal/webhookgenerator/admission/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package admission

import (
"errors"
"fmt"
"regexp"
"strings"
"sync"

admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/internal/webhookgenerator/types"
)

// Webhook represents each individual webhook.
type Webhook struct {
// Name is the name of the webhook
Name string
// Type is the webhook type, i.e. mutating, validating
Type types.WebhookType
// Path is the path this webhook will serve.
Path string
// Rules maps to the Rules field in admissionregistrationv1beta1.Webhook
Rules []admissionregistrationv1beta1.RuleWithOperations
// FailurePolicy maps to the FailurePolicy field in admissionregistrationv1beta1.Webhook
// This optional. If not set, will be defaulted to Ignore (fail-open) by the server.
// More details: https://github.com/kubernetes/api/blob/f5c295feaba2cbc946f0bbb8b535fc5f6a0345ee/admissionregistration/v1beta1/types.go#L144-L147
FailurePolicy *admissionregistrationv1beta1.FailurePolicyType
// NamespaceSelector maps to the NamespaceSelector field in admissionregistrationv1beta1.Webhook
// This optional.
NamespaceSelector *metav1.LabelSelector

once sync.Once
}

func (w *Webhook) setDefaults() {
if len(w.Path) == 0 {
if len(w.Rules) == 0 || len(w.Rules[0].Resources) == 0 {
// can't do defaulting, skip it.
return
}
if w.Type == types.WebhookTypeMutating {
w.Path = "/mutate-" + w.Rules[0].Resources[0]
} else if w.Type == types.WebhookTypeValidating {
w.Path = "/validate-" + w.Rules[0].Resources[0]
}
}
if len(w.Name) == 0 {
reg := regexp.MustCompile("[^a-zA-Z0-9]+")
processedPath := strings.ToLower(reg.ReplaceAllString(w.Path, ""))
w.Name = processedPath + ".example.com"
}
}

// GetName returns the name of the webhook.
func (w *Webhook) GetName() string {
w.once.Do(w.setDefaults)
return w.Name
}

// GetPath returns the path that the webhook registered.
func (w *Webhook) GetPath() string {
w.once.Do(w.setDefaults)
return w.Path
}

// GetType returns the type of the webhook.
func (w *Webhook) GetType() types.WebhookType {
w.once.Do(w.setDefaults)
return w.Type
}

// Validate validates if the webhook is valid.
func (w *Webhook) Validate() error {
w.once.Do(w.setDefaults)
if len(w.Rules) == 0 {
return errors.New("field Rules should not be empty")
}
if len(w.Name) == 0 {
return errors.New("field Name should not be empty")
}
if w.Type != types.WebhookTypeMutating && w.Type != types.WebhookTypeValidating {
return fmt.Errorf("unsupported Type: %v, only WebhookTypeMutating and WebhookTypeValidating are supported", w.Type)
}
if len(w.Path) == 0 {
return errors.New("field Path should not be empty")
}
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,4 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

/*
Package generator provides an interface and implementation to provision certificates.
Create an instance of certGenerator.
cg := SelfSignedCertGenerator{}
Generate the certificates.
certs, err := cg.Generate("foo.bar.com")
if err != nil {
// handle error
}
*/
package generator
package webhook
Loading

0 comments on commit b2ea9dc

Please sign in to comment.