Skip to content

✨ Move webhook generator #136

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

Merged
merged 3 commits into from
Feb 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
885 changes: 75 additions & 810 deletions Gopkg.lock

Large diffs are not rendered by default.

45 changes: 4 additions & 41 deletions Gopkg.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
required = [
"github.com/emicklei/go-restful",
"github.com/go-openapi/spec",
"github.com/onsi/ginkgo", # for integration testing
"github.com/spf13/pflag",
"k8s.io/client-go/plugin/pkg/client/auth/gcp", # for development against gcp
"k8s.io/code-generator/cmd/deepcopy-gen", # for go generate
"sigs.k8s.io/testing_frameworks/integration", # for integration testing
]

[[constraint]]
name="sigs.k8s.io/controller-runtime"
version="v0.1.1"
ignored = [
"sigs.k8s.io/controller-tools/testData/*", # it's just testdata
]

[[constraint]]
name="k8s.io/api"
Expand All @@ -24,34 +14,10 @@ required = [
name="k8s.io/apimachinery"
version="kubernetes-1.13.1"

[[constraint]]
name="k8s.io/code-generator"
version="kubernetes-1.13.1"

[[constraint]]
name="k8s.io/client-go"
version="kubernetes-1.13.1"

[[constraint]]
name = "github.com/onsi/ginkgo"
version = "v1.5.0"

[[constraint]]
name = "github.com/onsi/gomega"
version = "v1.4.0"

[[constraint]]
name = "github.com/spf13/afero"
version = "v1.1.1"

[[constraint]]
name = "gopkg.in/yaml.v2"
version = "v2.2.1"

[[constraint]]
name = "github.com/emicklei/go-restful"
version = "v2.7.1"

[[constraint]]
name = "github.com/spf13/cobra"
version = "v0.0.3"
Expand All @@ -60,10 +26,6 @@ required = [
name = "github.com/spf13/pflag"
version = "v1.0.1"

[[constraint]]
name = "github.com/spf13/viper"
version = "v1.0.2"

[[constraint]]
name = "github.com/ghodss/yaml"
version = "1.0.0"
Expand All @@ -83,3 +45,4 @@ required = [

[prune]
go-tests = true
unused-packages = true
15 changes: 14 additions & 1 deletion cmd/controller-gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,19 @@ Usage:
log.Fatal(err)
}
fmt.Printf("RBAC manifests generated under '%s' \n", rbacOptions.OutputDir)

o := &webhook.Options{
WriterOptions: webhook.WriterOptions{
InputDir: filepath.Join(projectDir, "pkg"),
OutputDir: filepath.Join(projectDir, "config", "webhook"),
PatchOutputDir: filepath.Join(projectDir, "config", "default"),
},
}
o.SetDefaults()
if err := webhook.Generate(o); err != nil {
log.Fatal(err)
}
fmt.Printf("webhook manifests generated under '%s' directory\n", o.OutputDir)
},
}
f := cmd.Flags()
Expand All @@ -167,7 +180,7 @@ Usage:
}

func newWebhookCmd() *cobra.Command {
o := &webhook.ManifestOptions{}
o := &webhook.Options{}
o.SetDefaults()

cmd := &cobra.Command{
Expand Down
5 changes: 3 additions & 2 deletions pkg/crd/generator/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ func TestGenerator(t *testing.T) {
if err != nil {
t.Fatalf("unable to get current directory: %v", err)
}
testDataDir := filepath.Join(currDir, "..", "..", "..", "testData")
// in-memory file system for storing the generated CRDs
outFs := afero.NewMemMapFs()
g := &crdgenerator.Generator{
OutFs: outFs,
OutputDir: "/tmp",
RootPath: filepath.Join(currDir, "testData"),
RootPath: testDataDir,
}
err = g.ValidateAndInitFields()
if err != nil {
Expand All @@ -54,7 +55,7 @@ func TestGenerator(t *testing.T) {
if err != nil {
t.Fatalf("reading file failed %v", err)
}
expectedContent, err := ioutil.ReadFile(filepath.Join(currDir, "testData", "config", "crds", f))
expectedContent, err := ioutil.ReadFile(filepath.Join(testDataDir, "config", "crds", f))
if err != nil {
t.Fatalf("reading file failed %v", err)
}
Expand Down
1 change: 0 additions & 1 deletion pkg/crd/generator/testData/vendor

This file was deleted.

89 changes: 89 additions & 0 deletions pkg/webhook/admission.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
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 webhook

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

admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// admissionWebhook contains bits needed for generating a admissionWebhook Configuration
type admissionWebhook struct {
// name is the name of the webhook
name string
// typ is the webhook type, i.e. mutating, validating
typ webhookType
// path is the path this webhook will serve.
path string
// rules maps to the rules field in admissionregistrationv1beta1.admissionWebhook
rules []admissionregistrationv1beta1.RuleWithOperations
// failurePolicy maps to the failurePolicy field in admissionregistrationv1beta1.admissionWebhook
// 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.admissionWebhook
// This optional.
namespaceSelector *metav1.LabelSelector
}

func (w *admissionWebhook) 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.typ == mutatingWebhook {
w.path = "/mutate-" + w.rules[0].Resources[0]
} else if w.typ == validatingWebhook {
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"
}
}

var _ webhook = &admissionWebhook{}

// GetType returns the type of the webhook.
func (w *admissionWebhook) GetType() webhookType {
return w.typ
}

// Validate validates if the webhook is valid.
func (w *admissionWebhook) Validate() error {
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.typ != mutatingWebhook && w.typ != validatingWebhook {
return fmt.Errorf("unsupported Type: %v, only mutatingWebhook and validatingWebhook are supported", w.typ)
}
if len(w.path) == 0 {
return errors.New("field path should not be empty")
}
return nil
}
Loading