Skip to content

Commit

Permalink
Refractor webhook code
Browse files Browse the repository at this point in the history
Signed-off-by: wenqi <[email protected]>
  • Loading branch information
wenqi authored and wenqi committed Apr 8, 2019
1 parent 8d01af0 commit f964c88
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 94 deletions.
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o ${GOBIN}/${PROJECT_NAME} \
# =============================================================================
FROM alpine:3.7 AS final

RUN apk add --update \
sudo \
libcap

ARG PROJECT_NAME=pravega-operator
ARG REPO_PATH=github.com/pravega/$PROJECT_NAME

COPY --from=go-builder ${GOBIN}/${PROJECT_NAME} /usr/local/bin/${PROJECT_NAME}
RUN sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/${PROJECT_NAME}

RUN adduser -D ${PROJECT_NAME}
USER ${PROJECT_NAME}
Expand Down
6 changes: 6 additions & 0 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

"github.com/pravega/pravega-operator/pkg/apis"
"github.com/pravega/pravega-operator/pkg/controller"
"github.com/pravega/pravega-operator/pkg/webhook"
controllerconfig "github.com/pravega/pravega-operator/pkg/controller/config"
"github.com/pravega/pravega-operator/pkg/version"

Expand Down Expand Up @@ -102,6 +103,11 @@ func main() {
log.Fatal(err)
}

// Setup webhook
if err := webhook.AddToManager(mgr); err != nil {
log.Fatal(err)
}

log.Print("Starting the Cmd")

// Start the Cmd
Expand Down
13 changes: 12 additions & 1 deletion deploy/operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ spec:
metadata:
labels:
name: pravega-operator
component: operator
spec:
serviceAccountName: pravega-operator
containers:
- name: pravega-operator
image: pravega/pravega-operator:latest
image: tristan1900/pravega-operator:webhook0.0.8
ports:
- containerPort: 60000
name: metrics
Expand All @@ -33,3 +34,13 @@ spec:
fieldPath: metadata.name
- name: OPERATOR_NAME
value: "pravega-operator"
- name: SECRET_NAME
value: "admission-webhook-server-secret"
volumeMounts:
- name: cert
mountPath: "/var/run/secrets/kubernetes.io/"
volumes:
- name: cert
secret:
secretName: admission-webhook-server-secret

40 changes: 0 additions & 40 deletions pkg/controller/pravegacluster/pravegacluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ package pravegacluster
import (
"context"
"fmt"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder"
"time"

pravegav1alpha1 "github.com/pravega/pravega-operator/pkg/apis/pravega/v1alpha1"
Expand All @@ -24,7 +23,6 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
Expand All @@ -35,8 +33,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/webhook"

log "github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -69,42 +65,6 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
return err
}

admissionWh, err := builder.NewWebhookBuilder().
Mutating().
Operations(admissionregistrationv1beta1.Create).
ForType(&pravegav1alpha1.PravegaCluster{}).
Handlers(&podAnnotator{}).
WithManager(mgr).
Build()
if err != nil {
fmt.Printf("Failed to create webhook: %v", err)
}

svr, err := webhook.NewServer("foo-admission-server", mgr, webhook.ServerOptions{
//CertDir: "/tmp/cert",
BootstrapOptions: &webhook.BootstrapOptions{
Secret: &types.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{
"component": "operator",
},
},
},
})
if err != nil {
// handle error
fmt.Printf("Failed to create webhook server: %v", err)
}

svr.Register(admissionWh)

return nil
}

Expand Down
53 changes: 0 additions & 53 deletions pkg/controller/pravegacluster/webhook.go

This file was deleted.

34 changes: 34 additions & 0 deletions pkg/webhook/add_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) 2019 Dell Inc., or its subsidiaries. All Rights Reserved.
*
* 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
*/

package webhook

import (
"sigs.k8s.io/controller-runtime/pkg/manager"
)

// AddToManagerFuncs is a list of functions to add all Webhooks to the Manager
var AddToManagerFuncs []func(manager.Manager) error

func init() {
// AddToManagerFuncs is a list of functions to create Webhooks and add them to a manager.
AddToManagerFuncs = append(AddToManagerFuncs, Add)
}

// AddToManager adds all Webhooks to the Manager
func AddToManager(m manager.Manager) error {
for _, f := range AddToManagerFuncs {
if err := f(m); err != nil {
return err
}
}
return nil
}

145 changes: 145 additions & 0 deletions pkg/webhook/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
* Copyright (c) 2019 Dell Inc., or its subsidiaries. All Rights Reserved.
*
* 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
*/

package webhook

import (
"context"
"k8s.io/apimachinery/pkg/runtime"
"net/http"
"os"

pravegav1alpha1 "github.com/pravega/pravega-operator/pkg/apis/pravega/v1alpha1"

admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
"k8s.io/apimachinery/pkg/types"

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder"
admissiontypes "sigs.k8s.io/controller-runtime/pkg/webhook/admission/types"
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"

log "github.com/sirupsen/logrus"
)

const (
CertDir = "/var/run/secrets/kubernetes.io/"
)

// Create webhook server and register webhook to it
func Add(mgr manager.Manager) error {
log.Printf("Initializing webhook")
svr, err := newWebhookServer(mgr)
if err != nil {
log.Printf("Failed to create webhook server: %v", err)
return err
}

wh, err := newValidatingWebhook(mgr)
if err != nil {
log.Printf("Failed to create validating webhook: %v", err)
return err
}

svr.Register(wh)
return nil
}

func newValidatingWebhook(mgr manager.Manager) (*admission.Webhook, error){
return builder.NewWebhookBuilder().
Mutating().
Operations(admissionregistrationv1beta1.Create).
ForType(&pravegav1alpha1.PravegaCluster{}).
Handlers(&pravegaWebhookHandler{}).
WithManager(mgr).
Build()
}

func newWebhookServer(mgr manager.Manager) (*webhook.Server, error) {
return webhook.NewServer("admission-webhook-server", mgr, webhook.ServerOptions{
CertDir: CertDir,
BootstrapOptions: &webhook.BootstrapOptions{
Secret: &types.NamespacedName{
Namespace: os.Getenv("WATCH_NAMESPACE"),
Name: os.Getenv("SECRET_NAME"),
},

// TODO: garbage collect webhook service
Service: &webhook.Service{
Namespace: os.Getenv("WATCH_NAMESPACE"),
Name: "admission-webhook-server-service",
Selectors: map[string]string{
"component": "operator",
},
},
},
})
}

type pravegaWebhookHandler struct {
client client.Client
scheme *runtime.Scheme
decoder admissiontypes.Decoder
}

var _ admission.Handler = &pravegaWebhookHandler{}

func (pwh *pravegaWebhookHandler) Handle(ctx context.Context, req admissiontypes.Request) admissiontypes.Response {
log.Printf("Webhook is handling incoming requests")
pravega := &pravegav1alpha1.PravegaCluster{}

if err := pwh.decoder.Decode(req, pravega); err != nil {
return admission.ErrorResponse(http.StatusBadRequest, err)
}
copy := pravega.DeepCopy()

err := pwh.validatePravegaManifest(ctx, copy)
if err != nil {
return admission.ErrorResponse(http.StatusInternalServerError, err)
}

return admission.ValidationResponse(true, "")
}


func (pwh *pravegaWebhookHandler) validatePravegaManifest(ctx context.Context, pod *pravegav1alpha1.PravegaCluster) error {
// TODO: implement logic to validate a upgrade version
return nil
}

// pravegaWebhookHandler implements inject.Client.
var _ inject.Client = &pravegaWebhookHandler{}

// InjectClient injects the client into the pravegaWebhookHandler
func (pwh *pravegaWebhookHandler) InjectClient(c client.Client) error {
pwh.client = c
return nil
}

// pravegaWebhookHandler implements inject.Decoder.
var _ inject.Decoder = &pravegaWebhookHandler{}

// InjectDecoder injects the decoder into the pravegaWebhookHandler
func (pwh *pravegaWebhookHandler) InjectDecoder(d admissiontypes.Decoder) error {
pwh.decoder = d
return nil
}

// pravegaWebhookHandler implements inject.Scheme.
var _ inject.Scheme = &pravegaWebhookHandler{}

// InjectClient injects the client into the pravegaWebhookHandler
func (pwh *pravegaWebhookHandler) InjectScheme(s *runtime.Scheme) error {
pwh.scheme = s
return nil
}

0 comments on commit f964c88

Please sign in to comment.