From 8b2064058da4f95fd834e5d573e618511dfe3a6e Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Mon, 19 Aug 2019 10:14:07 -0700 Subject: [PATCH 1/5] use newer shared methods from pkg to start webhook. --- cmd/webhook/main.go | 126 ++++++++++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 50 deletions(-) diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index e4883109e5e..a855102bd6a 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -16,7 +16,13 @@ limitations under the License. package main import ( + "context" "flag" + "knative.dev/pkg/injection" + "knative.dev/pkg/injection/clients/kubeclient" + "knative.dev/pkg/injection/sharedmain" + "knative.dev/pkg/metrics" + "knative.dev/pkg/version" "log" "strconv" "time" @@ -27,24 +33,28 @@ import ( "github.com/kelseyhightower/envconfig" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" - eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" - messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" - "knative.dev/eventing/pkg/logconfig" "knative.dev/pkg/configmap" "knative.dev/pkg/logging" "knative.dev/pkg/logging/logkey" "knative.dev/pkg/signals" "knative.dev/pkg/system" "knative.dev/pkg/webhook" + + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" + "knative.dev/eventing/pkg/logconfig" ) type envConfig struct { RegistrationDelayTime string `envconfig:"REG_DELAY_TIME" required:"false"` } +var ( + masterURL = flag.String("master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.") + kubeconfig = flag.String("kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.") +) + func getRegistrationDelayTime(rdt string) time.Duration { var RegistrationDelay time.Duration @@ -62,44 +72,52 @@ func getRegistrationDelayTime(rdt string) time.Duration { func main() { flag.Parse() - // Read the logging config and setup a logger. - cm, err := configmap.Load("/etc/config-logging") + + // Set up signals so we handle the first shutdown signal gracefully. + ctx := signals.NewContext() + + cfg, err := sharedmain.GetConfig(*masterURL, *kubeconfig) if err != nil { - log.Fatalf("Error loading logging configuration: %v", err) + log.Fatal("Failed to get cluster config:", err) } - config, err := logging.NewConfigFromMap(cm) + + log.Printf("Registering %d clients", len(injection.Default.GetClients())) + log.Printf("Registering %d informer factories", len(injection.Default.GetInformerFactories())) + log.Printf("Registering %d informers", len(injection.Default.GetInformers())) + + ctx, _ = injection.Default.SetupInformers(ctx, cfg) + kubeClient := kubeclient.Get(ctx) + + config, err := sharedmain.GetLoggingConfig(ctx) if err != nil { - log.Fatalf("Error parsing logging configuration: %v", err) + log.Fatal("Error loading/parsing logging configuration:", err) } logger, atomicLevel := logging.NewLoggerFromConfig(config, logconfig.WebhookName()) defer logger.Sync() logger = logger.With(zap.String(logkey.ControllerType, logconfig.WebhookName())) - logger.Infow("Starting the Eventing Webhook") - - var env envConfig - if err := envconfig.Process("", &env); err != nil { - log.Fatal("Failed to process env var", zap.Error(err)) + if err := version.CheckMinimumVersion(kubeClient.Discovery()); err != nil { + logger.Fatalw("Version check failed", err) } - RegistrationDelay := getRegistrationDelayTime(env.RegistrationDelayTime) - // set up signals so we handle the first shutdown signal gracefully - stopCh := signals.SetupSignalHandler() - - clusterConfig, err := rest.InClusterConfig() - if err != nil { - logger.Fatalw("Failed to get in cluster config", zap.Error(err)) - } - - kubeClient, err := kubernetes.NewForConfig(clusterConfig) - if err != nil { - logger.Fatalw("Failed to get the client set", zap.Error(err)) - } + logger.Infow("Starting the Eventing Webhook") // Watch the logging config map and dynamically update logging levels. configMapWatcher := configmap.NewInformedWatcher(kubeClient, system.Namespace()) + // Watch the observability config map and dynamically update metrics exporter. + configMapWatcher.Watch(metrics.ConfigMapName(), metrics.UpdateExporterFromConfigMap(logconfig.WebhookName(), logger)) + // Watch the observability config map and dynamically update request logs. + configMapWatcher.Watch(logging.ConfigMapName(), logging.UpdateLevelFromConfigMap(logger, atomicLevel, logconfig.WebhookName())) - configMapWatcher.Watch(logconfig.ConfigMapName(), logging.UpdateLevelFromConfigMap(logger, atomicLevel, logconfig.WebhookName())) + if err = configMapWatcher.Start(ctx.Done()); err != nil { + logger.Fatalw("Failed to start the ConfigMap watcher", zap.Error(err)) + } + + var env envConfig + if err := envconfig.Process("", &env); err != nil { + log.Fatal("Failed to process env var", zap.Error(err)) + } + registrationDelay := getRegistrationDelayTime(env.RegistrationDelayTime) // Watch the default-ch-webhook ConfigMap and dynamically update the default // Channel CRD. @@ -107,7 +125,7 @@ func main() { eventingduckv1alpha1.ChannelDefaulterSingleton = chDefaulter configMapWatcher.Watch(defaultchannel.ConfigMapName, chDefaulter.UpdateConfigMap) - if err = configMapWatcher.Start(stopCh); err != nil { + if err = configMapWatcher.Start(ctx.Done()); err != nil { logger.Fatalf("failed to start webhook configmap watcher: %v", zap.Error(err)) } @@ -124,29 +142,37 @@ func main() { SecretName: "eventing-webhook-certs", WebhookName: "webhook.eventing.knative.dev", StatsReporter: stats, - RegistrationDelay: RegistrationDelay * time.Second, + RegistrationDelay: registrationDelay * time.Second, + } + + handlers := map[schema.GroupVersionKind]webhook.GenericCRD{ + // For group eventing.knative.dev, + eventingv1alpha1.SchemeGroupVersion.WithKind("Broker"): &eventingv1alpha1.Broker{}, + eventingv1alpha1.SchemeGroupVersion.WithKind("Subscription"): &eventingv1alpha1.Subscription{}, + eventingv1alpha1.SchemeGroupVersion.WithKind("Trigger"): &eventingv1alpha1.Trigger{}, + eventingv1alpha1.SchemeGroupVersion.WithKind("EventType"): &eventingv1alpha1.EventType{}, + // For group messaging.knative.dev. + messagingv1alpha1.SchemeGroupVersion.WithKind("InMemoryChannel"): &messagingv1alpha1.InMemoryChannel{}, + messagingv1alpha1.SchemeGroupVersion.WithKind("Sequence"): &messagingv1alpha1.Sequence{}, + messagingv1alpha1.SchemeGroupVersion.WithKind("Channel"): &messagingv1alpha1.Channel{}, } - controller := webhook.AdmissionController{ - Client: kubeClient, - Options: options, - Handlers: map[schema.GroupVersionKind]webhook.GenericCRD{ - // For group eventing.knative.dev, - eventingv1alpha1.SchemeGroupVersion.WithKind("Broker"): &eventingv1alpha1.Broker{}, - eventingv1alpha1.SchemeGroupVersion.WithKind("Subscription"): &eventingv1alpha1.Subscription{}, - eventingv1alpha1.SchemeGroupVersion.WithKind("Trigger"): &eventingv1alpha1.Trigger{}, - eventingv1alpha1.SchemeGroupVersion.WithKind("EventType"): &eventingv1alpha1.EventType{}, - // For group messaging.knative.dev. - messagingv1alpha1.SchemeGroupVersion.WithKind("InMemoryChannel"): &messagingv1alpha1.InMemoryChannel{}, - messagingv1alpha1.SchemeGroupVersion.WithKind("Sequence"): &messagingv1alpha1.Sequence{}, - messagingv1alpha1.SchemeGroupVersion.WithKind("Channel"): &messagingv1alpha1.Channel{}, - }, - Logger: logger, + + // Decorate contexts with the current state of the config. + ctxFunc := func(ctx context.Context) context.Context { + // TODO: implement upgrades when eventing needs it: + // return v1beta1.WithUpgradeViaDefaulting(store.ToContext(ctx)) + return ctx } + + controller, err := webhook.NewAdmissionController(kubeClient, options, handlers, logger, ctxFunc, true) + if err != nil { - logger.Fatalw("Failed to create the admission controller", zap.Error(err)) + logger.Fatalw("Failed to create admission controller", zap.Error(err)) } - if err = controller.Run(stopCh); err != nil { - logger.Errorw("controller.Run() failed", zap.Error(err)) + + if err = controller.Run(ctx.Done()); err != nil { + logger.Fatalw("Failed to start the admission controller", zap.Error(err)) } + logger.Infow("Webhook stopping") } From df0a7439567ad2bcfa11cb6fc3f62e96d2a8b53d Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Mon, 19 Aug 2019 10:32:00 -0700 Subject: [PATCH 2/5] update deps. --- Gopkg.lock | 10 + third_party/VENDOR-LICENSE | 33 ++ .../github.com/rogpeppe/go-internal/LICENSE | 27 ++ .../rogpeppe/go-internal/semver/semver.go | 388 ++++++++++++++++++ 4 files changed, 458 insertions(+) create mode 100644 vendor/github.com/rogpeppe/go-internal/LICENSE create mode 100644 vendor/github.com/rogpeppe/go-internal/semver/semver.go diff --git a/Gopkg.lock b/Gopkg.lock index ff89eeb9095..5de7b2c9876 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -492,6 +492,14 @@ revision = "b41be1df696709bb6395fe435af20370037c0b4c" version = "v1.1" +[[projects]] + digest = "1:7008ec21a0ce773bd21deefdb7d17fab8cb9f1ae0bc44026cdd2b658ab1582ca" + name = "github.com/rogpeppe/go-internal" + packages = ["semver"] + pruneopts = "NUT" + revision = "438578804ca6f31be148c27683afc419ce47c06e" + version = "v1.3.0" + [[projects]] digest = "1:d917313f309bda80d27274d53985bc65651f81a5b66b820749ac7f8ef061fd04" name = "github.com/sergi/go-diff" @@ -1242,6 +1250,7 @@ "tracing", "tracing/config", "tracker", + "version", "webhook", ] pruneopts = "T" @@ -1416,6 +1425,7 @@ "knative.dev/pkg/tracing", "knative.dev/pkg/tracing/config", "knative.dev/pkg/tracker", + "knative.dev/pkg/version", "knative.dev/pkg/webhook", "knative.dev/test-infra/scripts", "knative.dev/test-infra/shared/junit", diff --git a/third_party/VENDOR-LICENSE b/third_party/VENDOR-LICENSE index f0b3991818f..37ad01e0112 100644 --- a/third_party/VENDOR-LICENSE +++ b/third_party/VENDOR-LICENSE @@ -5713,6 +5713,39 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +=========================================================== +Import: knative.dev/eventing/vendor/github.com/rogpeppe/go-internal + +Copyright (c) 2018 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + =========================================================== Import: knative.dev/eventing/vendor/github.com/spf13/pflag diff --git a/vendor/github.com/rogpeppe/go-internal/LICENSE b/vendor/github.com/rogpeppe/go-internal/LICENSE new file mode 100644 index 00000000000..49ea0f92882 --- /dev/null +++ b/vendor/github.com/rogpeppe/go-internal/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2018 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/rogpeppe/go-internal/semver/semver.go b/vendor/github.com/rogpeppe/go-internal/semver/semver.go new file mode 100644 index 00000000000..4af7118e55d --- /dev/null +++ b/vendor/github.com/rogpeppe/go-internal/semver/semver.go @@ -0,0 +1,388 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package semver implements comparison of semantic version strings. +// In this package, semantic version strings must begin with a leading "v", +// as in "v1.0.0". +// +// The general form of a semantic version string accepted by this package is +// +// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] +// +// where square brackets indicate optional parts of the syntax; +// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; +// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers +// using only alphanumeric characters and hyphens; and +// all-numeric PRERELEASE identifiers must not have leading zeros. +// +// This package follows Semantic Versioning 2.0.0 (see semver.org) +// with two exceptions. First, it requires the "v" prefix. Second, it recognizes +// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) +// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. +package semver + +// parsed returns the parsed form of a semantic version string. +type parsed struct { + major string + minor string + patch string + short string + prerelease string + build string + err string +} + +// IsValid reports whether v is a valid semantic version string. +func IsValid(v string) bool { + _, ok := parse(v) + return ok +} + +// Canonical returns the canonical formatting of the semantic version v. +// It fills in any missing .MINOR or .PATCH and discards build metadata. +// Two semantic versions compare equal only if their canonical formattings +// are identical strings. +// The canonical invalid semantic version is the empty string. +func Canonical(v string) string { + p, ok := parse(v) + if !ok { + return "" + } + if p.build != "" { + return v[:len(v)-len(p.build)] + } + if p.short != "" { + return v + p.short + } + return v +} + +// Major returns the major version prefix of the semantic version v. +// For example, Major("v2.1.0") == "v2". +// If v is an invalid semantic version string, Major returns the empty string. +func Major(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return v[:1+len(pv.major)] +} + +// MajorMinor returns the major.minor version prefix of the semantic version v. +// For example, MajorMinor("v2.1.0") == "v2.1". +// If v is an invalid semantic version string, MajorMinor returns the empty string. +func MajorMinor(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + i := 1 + len(pv.major) + if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { + return v[:j] + } + return v[:i] + "." + pv.minor +} + +// Prerelease returns the prerelease suffix of the semantic version v. +// For example, Prerelease("v2.1.0-pre+meta") == "-pre". +// If v is an invalid semantic version string, Prerelease returns the empty string. +func Prerelease(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.prerelease +} + +// Build returns the build suffix of the semantic version v. +// For example, Build("v2.1.0+meta") == "+meta". +// If v is an invalid semantic version string, Build returns the empty string. +func Build(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.build +} + +// Compare returns an integer comparing two versions according to +// according to semantic version precedence. +// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. +// +// An invalid semantic version string is considered less than a valid one. +// All invalid semantic version strings compare equal to each other. +func Compare(v, w string) int { + pv, ok1 := parse(v) + pw, ok2 := parse(w) + if !ok1 && !ok2 { + return 0 + } + if !ok1 { + return -1 + } + if !ok2 { + return +1 + } + if c := compareInt(pv.major, pw.major); c != 0 { + return c + } + if c := compareInt(pv.minor, pw.minor); c != 0 { + return c + } + if c := compareInt(pv.patch, pw.patch); c != 0 { + return c + } + return comparePrerelease(pv.prerelease, pw.prerelease) +} + +// Max canonicalizes its arguments and then returns the version string +// that compares greater. +func Max(v, w string) string { + v = Canonical(v) + w = Canonical(w) + if Compare(v, w) > 0 { + return v + } + return w +} + +func parse(v string) (p parsed, ok bool) { + if v == "" || v[0] != 'v' { + p.err = "missing v prefix" + return + } + p.major, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad major version" + return + } + if v == "" { + p.minor = "0" + p.patch = "0" + p.short = ".0.0" + return + } + if v[0] != '.' { + p.err = "bad minor prefix" + ok = false + return + } + p.minor, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad minor version" + return + } + if v == "" { + p.patch = "0" + p.short = ".0" + return + } + if v[0] != '.' { + p.err = "bad patch prefix" + ok = false + return + } + p.patch, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad patch version" + return + } + if len(v) > 0 && v[0] == '-' { + p.prerelease, v, ok = parsePrerelease(v) + if !ok { + p.err = "bad prerelease" + return + } + } + if len(v) > 0 && v[0] == '+' { + p.build, v, ok = parseBuild(v) + if !ok { + p.err = "bad build" + return + } + } + if v != "" { + p.err = "junk on end" + ok = false + return + } + ok = true + return +} + +func parseInt(v string) (t, rest string, ok bool) { + if v == "" { + return + } + if v[0] < '0' || '9' < v[0] { + return + } + i := 1 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + if v[0] == '0' && i != 1 { + return + } + return v[:i], v[i:], true +} + +func parsePrerelease(v string) (t, rest string, ok bool) { + // "A pre-release version MAY be denoted by appending a hyphen and + // a series of dot separated identifiers immediately following the patch version. + // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." + if v == "" || v[0] != '-' { + return + } + i := 1 + start := 1 + for i < len(v) && v[i] != '+' { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i || isBadNum(v[start:i]) { + return + } + start = i + 1 + } + i++ + } + if start == i || isBadNum(v[start:i]) { + return + } + return v[:i], v[i:], true +} + +func parseBuild(v string) (t, rest string, ok bool) { + if v == "" || v[0] != '+' { + return + } + i := 1 + start := 1 + for i < len(v) { + if !isIdentChar(v[i]) { + return + } + if v[i] == '.' { + if start == i { + return + } + start = i + 1 + } + i++ + } + if start == i { + return + } + return v[:i], v[i:], true +} + +func isIdentChar(c byte) bool { + return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' +} + +func isBadNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) && i > 1 && v[0] == '0' +} + +func isNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) +} + +func compareInt(x, y string) int { + if x == y { + return 0 + } + if len(x) < len(y) { + return -1 + } + if len(x) > len(y) { + return +1 + } + if x < y { + return -1 + } else { + return +1 + } +} + +func comparePrerelease(x, y string) int { + // "When major, minor, and patch are equal, a pre-release version has + // lower precedence than a normal version. + // Example: 1.0.0-alpha < 1.0.0. + // Precedence for two pre-release versions with the same major, minor, + // and patch version MUST be determined by comparing each dot separated + // identifier from left to right until a difference is found as follows: + // identifiers consisting of only digits are compared numerically and + // identifiers with letters or hyphens are compared lexically in ASCII + // sort order. Numeric identifiers always have lower precedence than + // non-numeric identifiers. A larger set of pre-release fields has a + // higher precedence than a smaller set, if all of the preceding + // identifiers are equal. + // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < + // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." + if x == y { + return 0 + } + if x == "" { + return +1 + } + if y == "" { + return -1 + } + for x != "" && y != "" { + x = x[1:] // skip - or . + y = y[1:] // skip - or . + var dx, dy string + dx, x = nextIdent(x) + dy, y = nextIdent(y) + if dx != dy { + ix := isNum(dx) + iy := isNum(dy) + if ix != iy { + if ix { + return -1 + } else { + return +1 + } + } + if ix { + if len(dx) < len(dy) { + return -1 + } + if len(dx) > len(dy) { + return +1 + } + } + if dx < dy { + return -1 + } else { + return +1 + } + } + } + if x == "" { + return -1 + } else { + return +1 + } +} + +func nextIdent(x string) (dx, rest string) { + i := 0 + for i < len(x) && x[i] != '.' { + i++ + } + return x[:i], x[i:] +} From f287bce5bc292d4bd8fafd247ba1f67305a028a6 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Mon, 19 Aug 2019 10:33:47 -0700 Subject: [PATCH 3/5] lint. --- cmd/webhook/main.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index a855102bd6a..dca6cc09af8 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -18,14 +18,15 @@ package main import ( "context" "flag" + "log" + "strconv" + "time" + "knative.dev/pkg/injection" "knative.dev/pkg/injection/clients/kubeclient" "knative.dev/pkg/injection/sharedmain" "knative.dev/pkg/metrics" "knative.dev/pkg/version" - "log" - "strconv" - "time" "knative.dev/eventing/pkg/defaultchannel" From 331d6ceb6b85bdd85e3d54907734cfc66e43cac6 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 20 Aug 2019 08:15:23 -0700 Subject: [PATCH 4/5] fix crashloop. --- cmd/webhook/main.go | 42 +++++++++++++++++------------------------ config/500-webhook.yaml | 2 ++ 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index dca6cc09af8..8e5a573adc5 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -22,29 +22,25 @@ import ( "strconv" "time" - "knative.dev/pkg/injection" - "knative.dev/pkg/injection/clients/kubeclient" - "knative.dev/pkg/injection/sharedmain" - "knative.dev/pkg/metrics" - "knative.dev/pkg/version" - - "knative.dev/eventing/pkg/defaultchannel" - - "go.uber.org/zap" - "github.com/kelseyhightower/envconfig" + "go.uber.org/zap" "k8s.io/apimachinery/pkg/runtime/schema" + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" + "knative.dev/eventing/pkg/defaultchannel" + "knative.dev/eventing/pkg/logconfig" "knative.dev/pkg/configmap" + "knative.dev/pkg/injection" + "knative.dev/pkg/injection/clients/kubeclient" + "knative.dev/pkg/injection/sharedmain" "knative.dev/pkg/logging" "knative.dev/pkg/logging/logkey" + "knative.dev/pkg/metrics" "knative.dev/pkg/signals" "knative.dev/pkg/system" + "knative.dev/pkg/version" "knative.dev/pkg/webhook" - - eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" - eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" - messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" - "knative.dev/eventing/pkg/logconfig" ) type envConfig struct { @@ -110,6 +106,12 @@ func main() { // Watch the observability config map and dynamically update request logs. configMapWatcher.Watch(logging.ConfigMapName(), logging.UpdateLevelFromConfigMap(logger, atomicLevel, logconfig.WebhookName())) + // Watch the default-ch-webhook ConfigMap and dynamically update the default + // Channel CRD. + chDefaulter := defaultchannel.New(logger.Desugar()) + eventingduckv1alpha1.ChannelDefaulterSingleton = chDefaulter + configMapWatcher.Watch(defaultchannel.ConfigMapName, chDefaulter.UpdateConfigMap) + if err = configMapWatcher.Start(ctx.Done()); err != nil { logger.Fatalw("Failed to start the ConfigMap watcher", zap.Error(err)) } @@ -120,16 +122,6 @@ func main() { } registrationDelay := getRegistrationDelayTime(env.RegistrationDelayTime) - // Watch the default-ch-webhook ConfigMap and dynamically update the default - // Channel CRD. - chDefaulter := defaultchannel.New(logger.Desugar()) - eventingduckv1alpha1.ChannelDefaulterSingleton = chDefaulter - configMapWatcher.Watch(defaultchannel.ConfigMapName, chDefaulter.UpdateConfigMap) - - if err = configMapWatcher.Start(ctx.Done()); err != nil { - logger.Fatalf("failed to start webhook configmap watcher: %v", zap.Error(err)) - } - stats, err := webhook.NewStatsReporter() if err != nil { logger.Fatalw("failed to initialize the stats reporter", zap.Error(err)) diff --git a/config/500-webhook.yaml b/config/500-webhook.yaml index 10759ed5684..12cf552c8f8 100644 --- a/config/500-webhook.yaml +++ b/config/500-webhook.yaml @@ -48,6 +48,8 @@ spec: fieldPath: metadata.namespace - name: CONFIG_LOGGING_NAME value: config-logging + - name: METRICS_DOMAIN + value: knative.dev/eventing - name: WEBHOOK_NAME value: eventing-webhook - name: REG_DELAY_TIME From e6f3a49dd4d8eeb73bf5a8e09194c28297811913 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Tue, 20 Aug 2019 08:18:40 -0700 Subject: [PATCH 5/5] adding choice. --- cmd/webhook/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index 8e5a573adc5..49a92c61dd1 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -147,6 +147,7 @@ func main() { // For group messaging.knative.dev. messagingv1alpha1.SchemeGroupVersion.WithKind("InMemoryChannel"): &messagingv1alpha1.InMemoryChannel{}, messagingv1alpha1.SchemeGroupVersion.WithKind("Sequence"): &messagingv1alpha1.Sequence{}, + messagingv1alpha1.SchemeGroupVersion.WithKind("Choice"): &messagingv1alpha1.Choice{}, messagingv1alpha1.SchemeGroupVersion.WithKind("Channel"): &messagingv1alpha1.Channel{}, }