Skip to content
This repository was archived by the owner on Jun 14, 2018. It is now read-only.

add webhook validation #1158

Merged
merged 19 commits into from
Sep 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ go_repository(
name = "io_k8s_apiserver",
build_file_generation = "on",
build_file_name = "BUILD.bazel",
commit = "ab57ed5a72c3b67058f665d660e23bae18339fc2",
commit = "149fc2228647cea28b0670c240ec582e985e8eda", # Jul Aug 1, 2017
importpath = "k8s.io/apiserver",
)

Expand Down
26 changes: 13 additions & 13 deletions adapter/config/crd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (cl *Client) RegisterResources() error {
}

for _, schema := range cl.descriptor {
name := resourceName(schema.Plural) + "." + model.IstioAPIGroup
name := ResourceName(schema.Plural) + "." + model.IstioAPIGroup
crd := &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: meta_v1.ObjectMeta{
Name: name,
Expand All @@ -159,7 +159,7 @@ func (cl *Client) RegisterResources() error {
Version: model.IstioAPIVersion,
Scope: apiextensionsv1beta1.NamespaceScoped,
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Plural: resourceName(schema.Plural),
Plural: ResourceName(schema.Plural),
Kind: kabobCaseToCamelCase(schema.Type),
},
},
Expand All @@ -175,7 +175,7 @@ func (cl *Client) RegisterResources() error {
errPoll := wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) {
descriptor:
for _, schema := range cl.descriptor {
name := resourceName(schema.Plural) + "." + model.IstioAPIGroup
name := ResourceName(schema.Plural) + "." + model.IstioAPIGroup
crd, errGet := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Get(name, meta_v1.GetOptions{})
if errGet != nil {
return false, errGet
Expand Down Expand Up @@ -219,7 +219,7 @@ func (cl *Client) DeregisterResources() error {

var errs error
for _, schema := range cl.descriptor {
name := resourceName(schema.Plural) + "." + model.IstioAPIGroup
name := ResourceName(schema.Plural) + "." + model.IstioAPIGroup
err := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Delete(name, nil)
errs = multierror.Append(errs, err)
}
Expand All @@ -241,7 +241,7 @@ func (cl *Client) Get(typ, name, namespace string) (*model.Config, bool) {
config := knownTypes[typ].object.DeepCopyObject().(IstioObject)
err := cl.dynamic.Get().
Namespace(namespace).
Resource(resourceName(schema.Plural)).
Resource(ResourceName(schema.Plural)).
Name(name).
Do().Into(config)

Expand All @@ -250,7 +250,7 @@ func (cl *Client) Get(typ, name, namespace string) (*model.Config, bool) {
return nil, false
}

out, err := convertObject(schema, config, cl.domainSuffix)
out, err := ConvertObject(schema, config, cl.domainSuffix)
if err != nil {
glog.Warning(err)
return nil, false
Expand All @@ -269,15 +269,15 @@ func (cl *Client) Create(config model.Config) (string, error) {
return "", multierror.Prefix(err, "validation error:")
}

out, err := convertConfig(schema, config)
out, err := ConvertConfig(schema, config)
if err != nil {
return "", err
}

obj := knownTypes[schema.Type].object.DeepCopyObject().(IstioObject)
err = cl.dynamic.Post().
Namespace(out.GetObjectMeta().Namespace).
Resource(resourceName(schema.Plural)).
Resource(ResourceName(schema.Plural)).
Body(out).
Do().Into(obj)
if err != nil {
Expand All @@ -302,15 +302,15 @@ func (cl *Client) Update(config model.Config) (string, error) {
return "", fmt.Errorf("revision is required")
}

out, err := convertConfig(schema, config)
out, err := ConvertConfig(schema, config)
if err != nil {
return "", err
}

obj := knownTypes[schema.Type].object.DeepCopyObject().(IstioObject)
err = cl.dynamic.Put().
Namespace(out.GetObjectMeta().Namespace).
Resource(resourceName(schema.Plural)).
Resource(ResourceName(schema.Plural)).
Name(out.GetObjectMeta().Name).
Body(out).
Do().Into(obj)
Expand All @@ -330,7 +330,7 @@ func (cl *Client) Delete(typ, name, namespace string) error {

return cl.dynamic.Delete().
Namespace(namespace).
Resource(resourceName(schema.Plural)).
Resource(ResourceName(schema.Plural)).
Name(name).
Do().Error()
}
Expand All @@ -345,12 +345,12 @@ func (cl *Client) List(typ, namespace string) ([]model.Config, error) {
list := knownTypes[schema.Type].collection.DeepCopyObject().(IstioObjectList)
errs := cl.dynamic.Get().
Namespace(namespace).
Resource(resourceName(schema.Plural)).
Resource(ResourceName(schema.Plural)).
Do().Into(list)

out := make([]model.Config, 0)
for _, item := range list.GetItems() {
obj, err := convertObject(schema, item, cl.domainSuffix)
obj, err := ConvertObject(schema, item, cl.domainSuffix)
if err != nil {
errs = multierror.Append(errs, err)
} else {
Expand Down
10 changes: 5 additions & 5 deletions adapter/config/crd/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (c *controller) addInformer(schema model.ProtoSchema, namespace string, res
result = knownTypes[schema.Type].collection.DeepCopyObject()
err = c.client.dynamic.Get().
Namespace(namespace).
Resource(resourceName(schema.Plural)).
Resource(ResourceName(schema.Plural)).
VersionedParams(&opts, meta_v1.ParameterCodec).
Do().
Into(result)
Expand All @@ -82,7 +82,7 @@ func (c *controller) addInformer(schema model.ProtoSchema, namespace string, res
return c.client.dynamic.Get().
Prefix("watch").
Namespace(namespace).
Resource(resourceName(schema.Plural)).
Resource(ResourceName(schema.Plural)).
VersionedParams(&opts, meta_v1.ParameterCodec).
Watch()
})
Expand Down Expand Up @@ -141,7 +141,7 @@ func (c *controller) RegisterEventHandler(typ string, f func(model.Config, model
c.kinds[typ].handler.Append(func(object interface{}, ev model.Event) error {
item, ok := object.(IstioObject)
if ok {
config, err := convertObject(schema, item, c.client.domainSuffix)
config, err := ConvertObject(schema, item, c.client.domainSuffix)
if err != nil {
glog.Warningf("error translating object %#v", object)
} else {
Expand Down Expand Up @@ -199,7 +199,7 @@ func (c *controller) Get(typ, name, namespace string) (*model.Config, bool) {
return nil, false
}

config, err := convertObject(schema, obj, c.client.domainSuffix)
config, err := ConvertObject(schema, obj, c.client.domainSuffix)
if err != nil {
return nil, false
}
Expand Down Expand Up @@ -237,7 +237,7 @@ func (c *controller) List(typ, namespace string) ([]model.Config, error) {
continue
}

config, err := convertObject(schema, item, c.client.domainSuffix)
config, err := ConvertObject(schema, item, c.client.domainSuffix)
if err != nil {
errs = multierror.Append(errs, err)
} else {
Expand Down
17 changes: 9 additions & 8 deletions adapter/config/crd/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import (
"istio.io/pilot/model"
)

func convertObject(schema model.ProtoSchema, object IstioObject, domain string) (*model.Config, error) {
// ConvertObject converts an IstioObject k8s-style object to the
// internal configuration model.
func ConvertObject(schema model.ProtoSchema, object IstioObject, domain string) (*model.Config, error) {
data, err := schema.FromJSONMap(object.GetSpec())
if err != nil {
return nil, err
Expand All @@ -43,8 +45,8 @@ func convertObject(schema model.ProtoSchema, object IstioObject, domain string)
}, nil
}

// convertConfig translates Istio config to k8s config JSON
func convertConfig(schema model.ProtoSchema, config model.Config) (IstioObject, error) {
// ConvertConfig translates Istio config to k8s config JSON
func ConvertConfig(schema model.ProtoSchema, config model.Config) (IstioObject, error) {
spec, err := schema.ToJSONMap(config.Spec)
if err != nil {
return nil, err
Expand All @@ -62,9 +64,9 @@ func convertConfig(schema model.ProtoSchema, config model.Config) (IstioObject,
return out, nil
}

// resourceName converts "my-name" to "myname".
// ResourceName converts "my-name" to "myname".
// This is needed by k8s API server as dashes prevent kubectl from accessing CRDs
func resourceName(s string) string {
func ResourceName(s string) string {
return strings.Replace(s, "-", "", -1)
}

Expand All @@ -78,9 +80,8 @@ func kabobCaseToCamelCase(s string) string {
return out
}

// camelCaseToKabobCase converts "MyName" to "my-name"
// nolint: deadcode
func camelCaseToKabobCase(s string) string {
// CamelCaseToKabobCase converts "MyName" to "my-name"
func CamelCaseToKabobCase(s string) string {
var out bytes.Buffer
for i := range s {
if 'A' <= s[i] && s[i] <= 'Z' {
Expand Down
4 changes: 2 additions & 2 deletions adapter/config/crd/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ var (

func TestCamelKabob(t *testing.T) {
for _, tt := range camelKabobs {
s := camelCaseToKabobCase(tt.in)
s := CamelCaseToKabobCase(tt.in)
if s != tt.out {
t.Errorf("camelCaseToKabobCase(%q) => %q, want %q", tt.in, s, tt.out)
t.Errorf("CamelCaseToKabobCase(%q) => %q, want %q", tt.in, s, tt.out)
}
u := kabobCaseToCamelCase(tt.out)
if u != tt.in {
Expand Down
2 changes: 1 addition & 1 deletion bin/check.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
set -ex

buildifier -showlog -mode=check $(find . -type f \( -name 'BUILD' -or -name 'WORKSPACE' -or -wholename '.*bazel' -or -wholename '.*bzl' \) -print )
buildifier -showlog -mode=check $(find . -type f \( -name 'BUILD' -or -name 'WORKSPACE' -or -wholename '.*bazel$' -or -wholename '.*bzl$' \) -print )
Copy link
Member

Choose a reason for hiding this comment

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

good fix!


NUM_CPU=$(getconf _NPROCESSORS_ONLN)

Expand Down
1 change: 1 addition & 0 deletions cmd/pilot-discovery/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ go_library(
"//platform/consul:go_default_library",
"//platform/eureka:go_default_library",
"//platform/kube:go_default_library",
"//platform/kube/admit:go_default_library",
"//proxy:go_default_library",
"//proxy/envoy:go_default_library",
"//tools/version:go_default_library",
Expand Down
55 changes: 43 additions & 12 deletions cmd/pilot-discovery/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"istio.io/pilot/platform/consul"
"istio.io/pilot/platform/eureka"
"istio.io/pilot/platform/kube"
"istio.io/pilot/platform/kube/admit"
"istio.io/pilot/proxy"
"istio.io/pilot/proxy/envoy"
"istio.io/pilot/tools/version"
Expand All @@ -58,9 +59,10 @@ type args struct {
controllerOptions kube.ControllerOptions
discoveryOptions envoy.DiscoveryServiceOptions

registries []string
consul consulArgs
eureka eurekaArgs
registries []string
consul consulArgs
eureka eurekaArgs
admissionArgs admit.ControllerOptions
}

var (
Expand Down Expand Up @@ -91,6 +93,15 @@ var (

stop := make(chan struct{})

if flags.controllerOptions.Namespace == "" {
flags.controllerOptions.Namespace = os.Getenv("POD_NAMESPACE")
}

_, client, kuberr := kube.CreateInterface(flags.kubeconfig)
if kuberr != nil {
return multierror.Prefix(kuberr, "failed to connect to Kubernetes API.")
}

configClient, err := crd.NewClient(flags.kubeconfig, model.ConfigDescriptor{
model.RouteRule,
model.EgressRule,
Expand All @@ -116,15 +127,6 @@ var (
glog.V(2).Infof("Adding %s registry adapter", serviceRegistry)
switch serviceRegistry {
case platform.KubernetesRegistry:
_, client, kuberr := kube.CreateInterface(flags.kubeconfig)
if kuberr != nil {
return multierror.Prefix(kuberr, "failed to connect to Kubernetes API.")
}

if flags.controllerOptions.Namespace == "" {
flags.controllerOptions.Namespace = os.Getenv("POD_NAMESPACE")
}

kubectl := kube.NewController(client, mesh, flags.controllerOptions)
serviceControllers.AddRegistry(
aggregate.Registry{
Expand Down Expand Up @@ -196,6 +198,22 @@ var (
return fmt.Errorf("failed to create discovery service: %v", err)
}

// Set up configuration validation admission
// controller. Fill in remaining admission controller
// options
flags.admissionArgs.Descriptor = configClient.ConfigDescriptor()
flags.admissionArgs.ServiceNamespace = flags.controllerOptions.Namespace
flags.admissionArgs.DomainSuffix = flags.controllerOptions.DomainSuffix
flags.admissionArgs.ValidateNamespaces = []string{
flags.controllerOptions.Namespace,
flags.controllerOptions.WatchedNamespace,
}
admissionController, err := admit.NewController(client, flags.admissionArgs)
if err != nil {
return fmt.Errorf("failed to create validation admission controller: %v", err)
}

go admissionController.Run(stop)
go serviceControllers.Run(stop)
go configController.Run(stop)
go discovery.Run()
Expand Down Expand Up @@ -238,6 +256,19 @@ func init() {
discoveryCmd.PersistentFlags().StringVar(&flags.eureka.serverURL, "eurekaserverURL", "",
"URL for the Eureka server")

discoveryCmd.PersistentFlags().StringVar(&flags.admissionArgs.ExternalAdmissionWebhookName,
"admission-webhook-name", "pilot-webhook.istio.io", "Webhook name for Pilot admission controller")
discoveryCmd.PersistentFlags().StringVar(&flags.admissionArgs.ServiceName,
"admission-service", "istio-pilot-external",
"Service name the admission controller uses during registration")
discoveryCmd.PersistentFlags().IntVar(&flags.admissionArgs.Port, "admission-service-port", 443,
"HTTPS port of the admission service. Must be 443 if service has more than one port ")
discoveryCmd.PersistentFlags().StringVar(&flags.admissionArgs.SecretName, "admission-secret", "pilot-webhook",
"Name of k8s secret for pilot webhook certs")
discoveryCmd.PersistentFlags().DurationVar(&flags.admissionArgs.RegistrationDelay,
"admission-registration-delay", 5*time.Second,
"Time to delay webhook registration after starting webhook server")

cmd.AddFlags(rootCmd)
rootCmd.AddCommand(discoveryCmd)
rootCmd.AddCommand(cmd.VersionCmd)
Expand Down
1 change: 1 addition & 0 deletions model/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ go_test(

go_test(
name = "go_default_xtest",
size = "small",
srcs = ["config_test.go"],
deps = [
":go_default_library",
Expand Down
46 changes: 46 additions & 0 deletions platform/kube/admit/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "go_default_library",
srcs = ["admit.go"],
visibility = ["//visibility:public"],
deps = [
"//adapter/config/crd:go_default_library",
"//model:go_default_library",
"@com_github_ghodss_yaml//:go_default_library",
"@com_github_golang_glog//:go_default_library",
"@io_k8s_api//admission/v1alpha1:go_default_library",
"@io_k8s_api//admissionregistration/v1alpha1:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
"@io_k8s_apimachinery//pkg/api/errors:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/fields:go_default_library",
"@io_k8s_apiserver//pkg/admission:go_default_library",
"@io_k8s_client_go//kubernetes:go_default_library",
"@io_k8s_client_go//kubernetes/typed/admissionregistration/v1alpha1:go_default_library",
"@io_k8s_client_go//tools/cache:go_default_library",
],
)

go_test(
name = "go_default_test",
size = "small",
srcs = ["admit_test.go"],
data = glob(["testdata/**"]),
library = ":go_default_library",
deps = [
"//adapter/config/crd:go_default_library",
"//model:go_default_library",
"//model/test:go_default_library",
"//platform/kube:go_default_library",
"//platform/kube/admit/testcerts:go_default_library",
"//test/mock:go_default_library",
"@io_k8s_api//admission/v1alpha1:go_default_library",
"@io_k8s_api//admissionregistration/v1alpha1:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
"@io_k8s_apiserver//pkg/admission:go_default_library",
"@io_k8s_client_go//kubernetes:go_default_library",
"@io_k8s_client_go//kubernetes/fake:go_default_library",
],
)
Loading