diff --git a/go.mod b/go.mod index d049aede12..bb312c57b0 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,11 @@ require ( contrib.go.opencensus.io/exporter/prometheus v0.1.0 // indirect contrib.go.opencensus.io/exporter/stackdriver v0.12.5 // indirect; indirect needed by knative serving github.com/google/go-containerregistry v0.0.0-20191029173801-50b26ee28691 // indirect + github.com/markbates/inflect v1.0.4 // indirect github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.8.1 + github.com/robfig/cron v1.2.0 // indirect github.com/spf13/cobra v0.0.5 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.4.0 @@ -16,7 +18,8 @@ require ( k8s.io/apimachinery v0.0.0-20190817020851-f2f3a405f61d k8s.io/cli-runtime v0.0.0-20190819144027-541433d7ce35 k8s.io/client-go v0.0.0-20190819141724-e14f31a72a77 - knative.dev/pkg v0.0.0-20191022181926-0b19b4ad9139 + knative.dev/eventing v0.10.0 + knative.dev/pkg v0.0.0-20191025185335-cad41c40ccb5 knative.dev/serving v0.10.0 knative.dev/test-infra v0.0.0-20190730202142-17f2331e80ad sigs.k8s.io/yaml v1.1.0 diff --git a/go.sum b/go.sum index 7336aa7091..3a47ecf30a 100644 --- a/go.sum +++ b/go.sum @@ -104,6 +104,8 @@ github.com/go-openapi/swag v0.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/envy v1.6.5 h1:X3is06x7v0nW2xiy2yFbbIjwHz57CD6z6MkvqULTCm8= +github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= @@ -182,6 +184,8 @@ github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be h1:AHimNtVIpiBjPUhEF5KNCkrUyqTSA5zWUl8sQ2bfGBE= @@ -209,6 +213,8 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3 github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/markbates/inflect v1.0.4 h1:5fh1gzTFhfae06u3hzHYO9xe3l3v3nW5Pwt3naLTP5g= +github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a h1:+J2gw7Bw77w/fbK7wnNJJDKmw1IbWft2Ul5BzrG1Qm8= github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= @@ -273,6 +279,8 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzr github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= @@ -520,8 +528,10 @@ k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKf k8s.io/kubernetes v1.11.10/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20190221042446-c2654d5206da h1:ElyM7RPonbKnQqOcw7dG2IK5uvQQn3b/WPHqD5mBvP4= k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -knative.dev/pkg v0.0.0-20191022181926-0b19b4ad9139 h1:wUapryP4MZmajUymSs5i3rL5Xh+SoZAqw/M5aFf0wvA= -knative.dev/pkg v0.0.0-20191022181926-0b19b4ad9139/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q= +knative.dev/eventing v0.10.0 h1:dDrOjBWWgloOCUjxR8ixUIh8nqCTbmM5BbGo8rvf1bc= +knative.dev/eventing v0.10.0/go.mod h1:UxweNv8yXhsdHJitcb9R6rmfNaUD2DFi9GWwNRyIs58= +knative.dev/pkg v0.0.0-20191025185335-cad41c40ccb5 h1:Bkxj/2GVEGaDd/gL57Egyn/h9HCGU9C8Z4FcIlcm/2A= +knative.dev/pkg v0.0.0-20191025185335-cad41c40ccb5/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q= knative.dev/serving v0.10.0 h1:T1csznAQrc/DvCE4KROz4NqOtJ24mnU9eF9RMeeYaCc= knative.dev/serving v0.10.0/go.mod h1:x2n255JS2XBI39tmjZ8CwTxIf9EKNMCrkVuiOttLRm0= knative.dev/test-infra v0.0.0-20190730202142-17f2331e80ad h1:pXN0DA06tXwn4vgzIqJ13rf4U412rS+fRRww1JWJ+o4= diff --git a/pkg/eventing/sources/v1alpha1/client.go b/pkg/eventing/sources/v1alpha1/client.go new file mode 100644 index 0000000000..fb972e3b4c --- /dev/null +++ b/pkg/eventing/sources/v1alpha1/client.go @@ -0,0 +1,27 @@ +// Copyright © 2019 The Knative 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 v1alpha1 + +import ( + client_v1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1" +) + +// knSourcesClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type knSourcesClient struct { + client client_v1alpha1.SourcesV1alpha1Interface + namespace string +} diff --git a/pkg/v1alpha1/client.go b/pkg/v1alpha1/client.go new file mode 100644 index 0000000000..fb972e3b4c --- /dev/null +++ b/pkg/v1alpha1/client.go @@ -0,0 +1,27 @@ +// Copyright © 2019 The Knative 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 v1alpha1 + +import ( + client_v1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1" +) + +// knSourcesClient is a combination of Sources client interface and namespace +// Temporarily help to add sources dependencies +// May be changed when adding real sources features +type knSourcesClient struct { + client client_v1alpha1.SourcesV1alpha1Interface + namespace string +} diff --git a/vendor/github.com/gobuffalo/envy/.env b/vendor/github.com/gobuffalo/envy/.env new file mode 100644 index 0000000000..33eeb3b13b --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/.env @@ -0,0 +1,5 @@ +# This is a comment +# We can use equal or colon notation +DIR: root +FLAVOUR: none +INSIDE_FOLDER=false \ No newline at end of file diff --git a/vendor/github.com/gobuffalo/envy/.gitignore b/vendor/github.com/gobuffalo/envy/.gitignore new file mode 100644 index 0000000000..3689718594 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/.gitignore @@ -0,0 +1,29 @@ +*.log +.DS_Store +doc +tmp +pkg +*.gem +*.pid +coverage +coverage.data +build/* +*.pbxuser +*.mode1v3 +.svn +profile +.console_history +.sass-cache/* +.rake_tasks~ +*.log.lck +solr/ +.jhw-cache/ +jhw.* +*.sublime* +node_modules/ +dist/ +generated/ +.vendor/ +bin/* +gin-bin +.idea/ diff --git a/vendor/github.com/gobuffalo/envy/.gometalinter.json b/vendor/github.com/gobuffalo/envy/.gometalinter.json new file mode 100644 index 0000000000..e4f65a36e8 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/.gometalinter.json @@ -0,0 +1,3 @@ +{ + "Enable": ["vet", "golint", "goimports", "deadcode", "gotype", "ineffassign", "misspell", "nakedret", "unconvert", "megacheck", "varcheck"] +} diff --git a/vendor/github.com/gobuffalo/envy/.travis.yml b/vendor/github.com/gobuffalo/envy/.travis.yml new file mode 100644 index 0000000000..cf1d2c7d42 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/.travis.yml @@ -0,0 +1,26 @@ +language: go + +sudo: false + +matrix: + include: + - go: "1.9.x" + - go: "1.10.x" + - go: "1.11.x" + env: + - GO111MODULE=off + - go: "1.11.x" + env: + - GO111MODULE=on + - go: "tip" + env: + - GO111MODULE=off + - go: "tip" + env: + - GO111MODULE=on + allow_failures: + - go: "tip" + +install: make deps + +script: make ci-test diff --git a/vendor/github.com/gobuffalo/envy/LICENSE.txt b/vendor/github.com/gobuffalo/envy/LICENSE.txt new file mode 100644 index 0000000000..123ddc0d80 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/LICENSE.txt @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright (c) 2018 Mark Bates + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/gobuffalo/envy/Makefile b/vendor/github.com/gobuffalo/envy/Makefile new file mode 100644 index 0000000000..b0db1c4f88 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/Makefile @@ -0,0 +1,46 @@ +TAGS ?= "sqlite" +GO_BIN ?= go + +install: + packr + $(GO_BIN) install -v . + +deps: + $(GO_BIN) get github.com/gobuffalo/release + $(GO_BIN) get github.com/gobuffalo/packr/packr + $(GO_BIN) get -tags ${TAGS} -t ./... +ifeq ($(GO111MODULE),on) + $(GO_BIN) mod tidy +endif + +build: + packr + $(GO_BIN) build -v . + +test: + packr + $(GO_BIN) test -tags ${TAGS} ./... + +ci-test: + $(GO_BIN) test -tags ${TAGS} -race ./... + +lint: + gometalinter --vendor ./... --deadline=1m --skip=internal + +update: + $(GO_BIN) get -u -tags ${TAGS} +ifeq ($(GO111MODULE),on) + $(GO_BIN) mod tidy +endif + packr + make test + make install +ifeq ($(GO111MODULE),on) + $(GO_BIN) mod tidy +endif + +release-test: + $(GO_BIN) test -tags ${TAGS} -race ./... + +release: + release -y -f version.go diff --git a/vendor/github.com/gobuffalo/envy/README.md b/vendor/github.com/gobuffalo/envy/README.md new file mode 100644 index 0000000000..f54462a773 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/README.md @@ -0,0 +1,93 @@ +# envy +[![Build Status](https://travis-ci.org/gobuffalo/envy.svg?branch=master)](https://travis-ci.org/gobuffalo/envy) + +Envy makes working with ENV variables in Go trivial. + +* Get ENV variables with default values. +* Set ENV variables safely without affecting the underlying system. +* Temporarily change ENV vars; useful for testing. +* Map all of the key/values in the ENV. +* Loads .env files (by using [godotenv](https://github.com/joho/godotenv/)) +* More! + +## Installation + +```text +$ go get -u github.com/gobuffalo/envy +``` + +## Usage + +```go +func Test_Get(t *testing.T) { + r := require.New(t) + r.NotZero(os.Getenv("GOPATH")) + r.Equal(os.Getenv("GOPATH"), envy.Get("GOPATH", "foo")) + r.Equal("bar", envy.Get("IDONTEXIST", "bar")) +} + +func Test_MustGet(t *testing.T) { + r := require.New(t) + r.NotZero(os.Getenv("GOPATH")) + v, err := envy.MustGet("GOPATH") + r.NoError(err) + r.Equal(os.Getenv("GOPATH"), v) + + _, err = envy.MustGet("IDONTEXIST") + r.Error(err) +} + +func Test_Set(t *testing.T) { + r := require.New(t) + _, err := envy.MustGet("FOO") + r.Error(err) + + envy.Set("FOO", "foo") + r.Equal("foo", envy.Get("FOO", "bar")) +} + +func Test_Temp(t *testing.T) { + r := require.New(t) + + _, err := envy.MustGet("BAR") + r.Error(err) + + envy.Temp(func() { + envy.Set("BAR", "foo") + r.Equal("foo", envy.Get("BAR", "bar")) + _, err = envy.MustGet("BAR") + r.NoError(err) + }) + + _, err = envy.MustGet("BAR") + r.Error(err) +} +``` +## .env files support + +Envy now supports loading `.env` files by using the [godotenv library](https://github.com/joho/godotenv/). +That means one can use and define multiple `.env` files which will be loaded on-demand. By default, no env files will be loaded. To load one or more, you need to call the `envy.Load` function in one of the following ways: + +```go +envy.Load() // 1 + +envy.Load("MY_ENV_FILE") // 2 + +envy.Load(".env", ".env.prod") // 3 + +envy.Load(".env", "NON_EXISTING_FILE") // 4 + +// 5 +envy.Load(".env") +envy.Load("NON_EXISTING_FILE") + +// 6 +envy.Load(".env", "NON_EXISTING_FILE", ".env.prod") +``` + +1. Will load the default `.env` file +2. Will load the file `MY_ENV_FILE`, **but not** `.env` +3. Will load the file `.env`, and after that will load the `.env.prod` file. If any variable is redefined in `. env.prod` it will be overwritten (will contain the `env.prod` value) +4. Will load the `.env` file and return an error as the second file does not exist. The values in `.env` will be loaded and available. +5. Same as 4 +6. Will load the `.env` file and return an error as the second file does not exist. The values in `.env` will be loaded and available, **but the ones in** `.env.prod` **won't**. diff --git a/vendor/github.com/gobuffalo/envy/envy.go b/vendor/github.com/gobuffalo/envy/envy.go new file mode 100644 index 0000000000..2b6eae1bc3 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/envy.go @@ -0,0 +1,238 @@ +/* +package envy makes working with ENV variables in Go trivial. + +* Get ENV variables with default values. +* Set ENV variables safely without affecting the underlying system. +* Temporarily change ENV vars; useful for testing. +* Map all of the key/values in the ENV. +* Loads .env files (by using [godotenv](https://github.com/joho/godotenv/)) +* More! +*/ +package envy + +import ( + "flag" + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" + "strconv" + "strings" + "sync" + + "github.com/joho/godotenv" +) + +var gil = &sync.RWMutex{} +var env = map[string]string{} + +func init() { + Load() + loadEnv() +} + +// Load the ENV variables to the env map +func loadEnv() { + gil.Lock() + defer gil.Unlock() + // Detect the Go version on the user system, not the one that was used to compile the binary + v := "" + out, err := exec.Command("go", "version").Output() + if err == nil { + // This will break when Go 2 lands + v = strings.Split(string(out), " ")[2][4:] + } else { + v = runtime.Version()[4:] + } + + goRuntimeVersion, _ := strconv.ParseFloat(runtime.Version()[4:], 64) + + goVersion, err := strconv.ParseFloat(v, 64) + if err != nil { + goVersion = goRuntimeVersion + } + + if os.Getenv("GO_ENV") == "" { + // if the flag "test.v" is *defined*, we're running as a unit test. Note that we don't care + // about v.Value (verbose test mode); we just want to know if the test environment has defined + // it. It's also possible that the flags are not yet fully parsed (i.e. flag.Parsed() == false), + // so we could not depend on v.Value anyway. + // + if v := flag.Lookup("test.v"); v != nil { + env["GO_ENV"] = "test" + } + } + + // set the GOPATH if using >= 1.8 and the GOPATH isn't set + if goVersion >= 8 && os.Getenv("GOPATH") == "" { + out, err := exec.Command("go", "env", "GOPATH").Output() + if err == nil { + gp := strings.TrimSpace(string(out)) + os.Setenv("GOPATH", gp) + } + } + + for _, e := range os.Environ() { + pair := strings.Split(e, "=") + env[pair[0]] = os.Getenv(pair[0]) + } +} + +// Reload the ENV variables. Useful if +// an external ENV manager has been used +func Reload() { + env = map[string]string{} + loadEnv() +} + +// Load .env files. Files will be loaded in the same order that are received. +// Redefined vars will override previously existing values. +// IE: envy.Load(".env", "test_env/.env") will result in DIR=test_env +// If no arg passed, it will try to load a .env file. +func Load(files ...string) error { + + // If no files received, load the default one + if len(files) == 0 { + err := godotenv.Overload() + if err == nil { + Reload() + } + return err + } + + // We received a list of files + for _, file := range files { + + // Check if it exists or we can access + if _, err := os.Stat(file); err != nil { + // It does not exist or we can not access. + // Return and stop loading + return err + } + + // It exists and we have permission. Load it + if err := godotenv.Overload(file); err != nil { + return err + } + + // Reload the env so all new changes are noticed + Reload() + + } + return nil +} + +// Get a value from the ENV. If it doesn't exist the +// default value will be returned. +func Get(key string, value string) string { + gil.RLock() + defer gil.RUnlock() + if v, ok := env[key]; ok { + return v + } + return value +} + +// Get a value from the ENV. If it doesn't exist +// an error will be returned +func MustGet(key string) (string, error) { + gil.RLock() + defer gil.RUnlock() + if v, ok := env[key]; ok { + return v, nil + } + return "", fmt.Errorf("could not find ENV var with %s", key) +} + +// Set a value into the ENV. This is NOT permanent. It will +// only affect values accessed through envy. +func Set(key string, value string) { + gil.Lock() + defer gil.Unlock() + env[key] = value +} + +// MustSet the value into the underlying ENV, as well as envy. +// This may return an error if there is a problem setting the +// underlying ENV value. +func MustSet(key string, value string) error { + gil.Lock() + defer gil.Unlock() + err := os.Setenv(key, value) + if err != nil { + return err + } + env[key] = value + return nil +} + +// Map all of the keys/values set in envy. +func Map() map[string]string { + gil.RLock() + defer gil.RUnlock() + cp := map[string]string{} + for k, v := range env { + cp[k] = v + } + return env +} + +// Temp makes a copy of the values and allows operation on +// those values temporarily during the run of the function. +// At the end of the function run the copy is discarded and +// the original values are replaced. This is useful for testing. +// Warning: This function is NOT safe to use from a goroutine or +// from code which may access any Get or Set function from a goroutine +func Temp(f func()) { + oenv := env + env = map[string]string{} + for k, v := range oenv { + env[k] = v + } + defer func() { env = oenv }() + f() +} + +func GoPath() string { + return Get("GOPATH", "") +} + +// GoPaths returns all possible GOPATHS that are set. +func GoPaths() []string { + gp := Get("GOPATH", "") + if runtime.GOOS == "windows" { + return strings.Split(gp, ";") // Windows uses a different separator + } + return strings.Split(gp, ":") +} + +func importPath(path string) string { + for _, gopath := range GoPaths() { + srcpath := filepath.Join(gopath, "src") + rel, err := filepath.Rel(srcpath, path) + if err == nil { + return filepath.ToSlash(rel) + } + } + + // fallback to trim + rel := strings.TrimPrefix(path, filepath.Join(GoPath(), "src")) + rel = strings.TrimPrefix(rel, string(filepath.Separator)) + return filepath.ToSlash(rel) +} + +func CurrentPackage() string { + pwd, _ := os.Getwd() + return importPath(pwd) +} + +func Environ() []string { + gil.RLock() + defer gil.RUnlock() + var e []string + for k, v := range env { + e = append(e, fmt.Sprintf("%s=%s", k, v)) + } + return e +} diff --git a/vendor/github.com/gobuffalo/envy/go.mod b/vendor/github.com/gobuffalo/envy/go.mod new file mode 100644 index 0000000000..149e25a459 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/go.mod @@ -0,0 +1,8 @@ +module github.com/gobuffalo/envy + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/joho/godotenv v1.3.0 + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.2.2 +) diff --git a/vendor/github.com/gobuffalo/envy/go.sum b/vendor/github.com/gobuffalo/envy/go.sum new file mode 100644 index 0000000000..868dbe8d81 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/go.sum @@ -0,0 +1,8 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/vendor/github.com/gobuffalo/envy/shoulders.md b/vendor/github.com/gobuffalo/envy/shoulders.md new file mode 100644 index 0000000000..0b22abc2a1 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/shoulders.md @@ -0,0 +1,10 @@ +# github.com/gobuffalo/envy Stands on the Shoulders of Giants + +github.com/gobuffalo/envy does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants this project would not be possible. Please make sure to check them out and thank them for all of their hard work. + +Thank you to the following **GIANTS**: + + +* [github.com/gobuffalo/envy](https://godoc.org/github.com/gobuffalo/envy) + +* [github.com/joho/godotenv](https://godoc.org/github.com/joho/godotenv) diff --git a/vendor/github.com/gobuffalo/envy/version.go b/vendor/github.com/gobuffalo/envy/version.go new file mode 100644 index 0000000000..8a3632fb18 --- /dev/null +++ b/vendor/github.com/gobuffalo/envy/version.go @@ -0,0 +1,3 @@ +package envy + +const Version = "v1.6.5" diff --git a/vendor/github.com/joho/godotenv/.gitignore b/vendor/github.com/joho/godotenv/.gitignore new file mode 100644 index 0000000000..e43b0f9889 --- /dev/null +++ b/vendor/github.com/joho/godotenv/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/vendor/github.com/joho/godotenv/.travis.yml b/vendor/github.com/joho/godotenv/.travis.yml new file mode 100644 index 0000000000..f0db1adcdb --- /dev/null +++ b/vendor/github.com/joho/godotenv/.travis.yml @@ -0,0 +1,8 @@ +language: go + +go: + - 1.x + +os: + - linux + - osx diff --git a/vendor/github.com/joho/godotenv/LICENCE b/vendor/github.com/joho/godotenv/LICENCE new file mode 100644 index 0000000000..e7ddd51be9 --- /dev/null +++ b/vendor/github.com/joho/godotenv/LICENCE @@ -0,0 +1,23 @@ +Copyright (c) 2013 John Barton + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/joho/godotenv/README.md b/vendor/github.com/joho/godotenv/README.md new file mode 100644 index 0000000000..4e8fcf2e9c --- /dev/null +++ b/vendor/github.com/joho/godotenv/README.md @@ -0,0 +1,163 @@ +# GoDotEnv [![Build Status](https://travis-ci.org/joho/godotenv.svg?branch=master)](https://travis-ci.org/joho/godotenv) [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4?svg=true)](https://ci.appveyor.com/project/joho/godotenv) [![Go Report Card](https://goreportcard.com/badge/github.com/joho/godotenv)](https://goreportcard.com/report/github.com/joho/godotenv) + +A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file) + +From the original Library: + +> Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables. +> +> But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped. + +It can be used as a library (for loading in env for your own daemons etc) or as a bin command. + +There is test coverage and CI for both linuxish and windows environments, but I make no guarantees about the bin version working on windows. + +## Installation + +As a library + +```shell +go get github.com/joho/godotenv +``` + +or if you want to use it as a bin command +```shell +go get github.com/joho/godotenv/cmd/godotenv +``` + +## Usage + +Add your application configuration to your `.env` file in the root of your project: + +```shell +S3_BUCKET=YOURS3BUCKET +SECRET_KEY=YOURSECRETKEYGOESHERE +``` + +Then in your Go app you can do something like + +```go +package main + +import ( + "github.com/joho/godotenv" + "log" + "os" +) + +func main() { + err := godotenv.Load() + if err != nil { + log.Fatal("Error loading .env file") + } + + s3Bucket := os.Getenv("S3_BUCKET") + secretKey := os.Getenv("SECRET_KEY") + + // now do something with s3 or whatever +} +``` + +If you're even lazier than that, you can just take advantage of the autoload package which will read in `.env` on import + +```go +import _ "github.com/joho/godotenv/autoload" +``` + +While `.env` in the project root is the default, you don't have to be constrained, both examples below are 100% legit + +```go +_ = godotenv.Load("somerandomfile") +_ = godotenv.Load("filenumberone.env", "filenumbertwo.env") +``` + +If you want to be really fancy with your env file you can do comments and exports (below is a valid env file) + +```shell +# I am a comment and that is OK +SOME_VAR=someval +FOO=BAR # comments at line end are OK too +export BAR=BAZ +``` + +Or finally you can do YAML(ish) style + +```yaml +FOO: bar +BAR: baz +``` + +as a final aside, if you don't want godotenv munging your env you can just get a map back instead + +```go +var myEnv map[string]string +myEnv, err := godotenv.Read() + +s3Bucket := myEnv["S3_BUCKET"] +``` + +... or from an `io.Reader` instead of a local file + +```go +reader := getRemoteFile() +myEnv, err := godotenv.Parse(reader) +``` + +... or from a `string` if you so desire + +```go +content := getRemoteFileContent() +myEnv, err := godotenv.Unmarshal(content) +``` + +### Command Mode + +Assuming you've installed the command as above and you've got `$GOPATH/bin` in your `$PATH` + +``` +godotenv -f /some/path/to/.env some_command with some args +``` + +If you don't specify `-f` it will fall back on the default of loading `.env` in `PWD` + +### Writing Env Files + +Godotenv can also write a map representing the environment to a correctly-formatted and escaped file + +```go +env, err := godotenv.Unmarshal("KEY=value") +err := godotenv.Write(env, "./.env") +``` + +... or to a string + +```go +env, err := godotenv.Unmarshal("KEY=value") +content, err := godotenv.Marshal(env) +``` + +## Contributing + +Contributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases. + +*code changes without tests will not be accepted* + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Added some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request + +## Releases + +Releases should follow [Semver](http://semver.org/) though the first couple of releases are `v1` and `v1.1`. + +Use [annotated tags for all releases](https://github.com/joho/godotenv/issues/30). Example `git tag -a v1.2.1` + +## CI + +Linux: [![Build Status](https://travis-ci.org/joho/godotenv.svg?branch=master)](https://travis-ci.org/joho/godotenv) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4)](https://ci.appveyor.com/project/joho/godotenv) + +## Who? + +The original library [dotenv](https://github.com/bkeepers/dotenv) was written by [Brandon Keepers](http://opensoul.org/), and this port was done by [John Barton](https://johnbarton.co/) based off the tests/fixtures in the original library. diff --git a/vendor/github.com/joho/godotenv/godotenv.go b/vendor/github.com/joho/godotenv/godotenv.go new file mode 100644 index 0000000000..29b436c77c --- /dev/null +++ b/vendor/github.com/joho/godotenv/godotenv.go @@ -0,0 +1,346 @@ +// Package godotenv is a go port of the ruby dotenv library (https://github.com/bkeepers/dotenv) +// +// Examples/readme can be found on the github page at https://github.com/joho/godotenv +// +// The TL;DR is that you make a .env file that looks something like +// +// SOME_ENV_VAR=somevalue +// +// and then in your go code you can call +// +// godotenv.Load() +// +// and all the env vars declared in .env will be available through os.Getenv("SOME_ENV_VAR") +package godotenv + +import ( + "bufio" + "errors" + "fmt" + "io" + "os" + "os/exec" + "regexp" + "sort" + "strings" +) + +const doubleQuoteSpecialChars = "\\\n\r\"!$`" + +// Load will read your env file(s) and load them into ENV for this process. +// +// Call this function as close as possible to the start of your program (ideally in main) +// +// If you call Load without any args it will default to loading .env in the current path +// +// You can otherwise tell it which files to load (there can be more than one) like +// +// godotenv.Load("fileone", "filetwo") +// +// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults +func Load(filenames ...string) (err error) { + filenames = filenamesOrDefault(filenames) + + for _, filename := range filenames { + err = loadFile(filename, false) + if err != nil { + return // return early on a spazout + } + } + return +} + +// Overload will read your env file(s) and load them into ENV for this process. +// +// Call this function as close as possible to the start of your program (ideally in main) +// +// If you call Overload without any args it will default to loading .env in the current path +// +// You can otherwise tell it which files to load (there can be more than one) like +// +// godotenv.Overload("fileone", "filetwo") +// +// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars. +func Overload(filenames ...string) (err error) { + filenames = filenamesOrDefault(filenames) + + for _, filename := range filenames { + err = loadFile(filename, true) + if err != nil { + return // return early on a spazout + } + } + return +} + +// Read all env (with same file loading semantics as Load) but return values as +// a map rather than automatically writing values into env +func Read(filenames ...string) (envMap map[string]string, err error) { + filenames = filenamesOrDefault(filenames) + envMap = make(map[string]string) + + for _, filename := range filenames { + individualEnvMap, individualErr := readFile(filename) + + if individualErr != nil { + err = individualErr + return // return early on a spazout + } + + for key, value := range individualEnvMap { + envMap[key] = value + } + } + + return +} + +// Parse reads an env file from io.Reader, returning a map of keys and values. +func Parse(r io.Reader) (envMap map[string]string, err error) { + envMap = make(map[string]string) + + var lines []string + scanner := bufio.NewScanner(r) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + if err = scanner.Err(); err != nil { + return + } + + for _, fullLine := range lines { + if !isIgnoredLine(fullLine) { + var key, value string + key, value, err = parseLine(fullLine, envMap) + + if err != nil { + return + } + envMap[key] = value + } + } + return +} + +//Unmarshal reads an env file from a string, returning a map of keys and values. +func Unmarshal(str string) (envMap map[string]string, err error) { + return Parse(strings.NewReader(str)) +} + +// Exec loads env vars from the specified filenames (empty map falls back to default) +// then executes the cmd specified. +// +// Simply hooks up os.Stdin/err/out to the command and calls Run() +// +// If you want more fine grained control over your command it's recommended +// that you use `Load()` or `Read()` and the `os/exec` package yourself. +func Exec(filenames []string, cmd string, cmdArgs []string) error { + Load(filenames...) + + command := exec.Command(cmd, cmdArgs...) + command.Stdin = os.Stdin + command.Stdout = os.Stdout + command.Stderr = os.Stderr + return command.Run() +} + +// Write serializes the given environment and writes it to a file +func Write(envMap map[string]string, filename string) error { + content, error := Marshal(envMap) + if error != nil { + return error + } + file, error := os.Create(filename) + if error != nil { + return error + } + _, err := file.WriteString(content) + return err +} + +// Marshal outputs the given environment as a dotenv-formatted environment file. +// Each line is in the format: KEY="VALUE" where VALUE is backslash-escaped. +func Marshal(envMap map[string]string) (string, error) { + lines := make([]string, 0, len(envMap)) + for k, v := range envMap { + lines = append(lines, fmt.Sprintf(`%s="%s"`, k, doubleQuoteEscape(v))) + } + sort.Strings(lines) + return strings.Join(lines, "\n"), nil +} + +func filenamesOrDefault(filenames []string) []string { + if len(filenames) == 0 { + return []string{".env"} + } + return filenames +} + +func loadFile(filename string, overload bool) error { + envMap, err := readFile(filename) + if err != nil { + return err + } + + currentEnv := map[string]bool{} + rawEnv := os.Environ() + for _, rawEnvLine := range rawEnv { + key := strings.Split(rawEnvLine, "=")[0] + currentEnv[key] = true + } + + for key, value := range envMap { + if !currentEnv[key] || overload { + os.Setenv(key, value) + } + } + + return nil +} + +func readFile(filename string) (envMap map[string]string, err error) { + file, err := os.Open(filename) + if err != nil { + return + } + defer file.Close() + + return Parse(file) +} + +func parseLine(line string, envMap map[string]string) (key string, value string, err error) { + if len(line) == 0 { + err = errors.New("zero length string") + return + } + + // ditch the comments (but keep quoted hashes) + if strings.Contains(line, "#") { + segmentsBetweenHashes := strings.Split(line, "#") + quotesAreOpen := false + var segmentsToKeep []string + for _, segment := range segmentsBetweenHashes { + if strings.Count(segment, "\"") == 1 || strings.Count(segment, "'") == 1 { + if quotesAreOpen { + quotesAreOpen = false + segmentsToKeep = append(segmentsToKeep, segment) + } else { + quotesAreOpen = true + } + } + + if len(segmentsToKeep) == 0 || quotesAreOpen { + segmentsToKeep = append(segmentsToKeep, segment) + } + } + + line = strings.Join(segmentsToKeep, "#") + } + + firstEquals := strings.Index(line, "=") + firstColon := strings.Index(line, ":") + splitString := strings.SplitN(line, "=", 2) + if firstColon != -1 && (firstColon < firstEquals || firstEquals == -1) { + //this is a yaml-style line + splitString = strings.SplitN(line, ":", 2) + } + + if len(splitString) != 2 { + err = errors.New("Can't separate key from value") + return + } + + // Parse the key + key = splitString[0] + if strings.HasPrefix(key, "export") { + key = strings.TrimPrefix(key, "export") + } + key = strings.Trim(key, " ") + + // Parse the value + value = parseValue(splitString[1], envMap) + return +} + +func parseValue(value string, envMap map[string]string) string { + + // trim + value = strings.Trim(value, " ") + + // check if we've got quoted values or possible escapes + if len(value) > 1 { + rs := regexp.MustCompile(`\A'(.*)'\z`) + singleQuotes := rs.FindStringSubmatch(value) + + rd := regexp.MustCompile(`\A"(.*)"\z`) + doubleQuotes := rd.FindStringSubmatch(value) + + if singleQuotes != nil || doubleQuotes != nil { + // pull the quotes off the edges + value = value[1 : len(value)-1] + } + + if doubleQuotes != nil { + // expand newlines + escapeRegex := regexp.MustCompile(`\\.`) + value = escapeRegex.ReplaceAllStringFunc(value, func(match string) string { + c := strings.TrimPrefix(match, `\`) + switch c { + case "n": + return "\n" + case "r": + return "\r" + default: + return match + } + }) + // unescape characters + e := regexp.MustCompile(`\\([^$])`) + value = e.ReplaceAllString(value, "$1") + } + + if singleQuotes == nil { + value = expandVariables(value, envMap) + } + } + + return value +} + +func expandVariables(v string, m map[string]string) string { + r := regexp.MustCompile(`(\\)?(\$)(\()?\{?([A-Z0-9_]+)?\}?`) + + return r.ReplaceAllStringFunc(v, func(s string) string { + submatch := r.FindStringSubmatch(s) + + if submatch == nil { + return s + } + if submatch[1] == "\\" || submatch[2] == "(" { + return submatch[0][1:] + } else if submatch[4] != "" { + return m[submatch[4]] + } + return s + }) +} + +func isIgnoredLine(line string) bool { + trimmedLine := strings.Trim(line, " \n\t") + return len(trimmedLine) == 0 || strings.HasPrefix(trimmedLine, "#") +} + +func doubleQuoteEscape(line string) string { + for _, c := range doubleQuoteSpecialChars { + toReplace := "\\" + string(c) + if c == '\n' { + toReplace = `\n` + } + if c == '\r' { + toReplace = `\r` + } + line = strings.Replace(line, string(c), toReplace, -1) + } + return line +} diff --git a/vendor/github.com/markbates/inflect/.gitignore b/vendor/github.com/markbates/inflect/.gitignore new file mode 100644 index 0000000000..3689718594 --- /dev/null +++ b/vendor/github.com/markbates/inflect/.gitignore @@ -0,0 +1,29 @@ +*.log +.DS_Store +doc +tmp +pkg +*.gem +*.pid +coverage +coverage.data +build/* +*.pbxuser +*.mode1v3 +.svn +profile +.console_history +.sass-cache/* +.rake_tasks~ +*.log.lck +solr/ +.jhw-cache/ +jhw.* +*.sublime* +node_modules/ +dist/ +generated/ +.vendor/ +bin/* +gin-bin +.idea/ diff --git a/vendor/github.com/markbates/inflect/.gometalinter.json b/vendor/github.com/markbates/inflect/.gometalinter.json new file mode 100644 index 0000000000..e4f65a36e8 --- /dev/null +++ b/vendor/github.com/markbates/inflect/.gometalinter.json @@ -0,0 +1,3 @@ +{ + "Enable": ["vet", "golint", "goimports", "deadcode", "gotype", "ineffassign", "misspell", "nakedret", "unconvert", "megacheck", "varcheck"] +} diff --git a/vendor/github.com/markbates/inflect/.hgignore b/vendor/github.com/markbates/inflect/.hgignore new file mode 100644 index 0000000000..6cc3d7ce11 --- /dev/null +++ b/vendor/github.com/markbates/inflect/.hgignore @@ -0,0 +1 @@ +swp$ diff --git a/vendor/github.com/markbates/inflect/.travis.yml b/vendor/github.com/markbates/inflect/.travis.yml new file mode 100644 index 0000000000..cf1d2c7d42 --- /dev/null +++ b/vendor/github.com/markbates/inflect/.travis.yml @@ -0,0 +1,26 @@ +language: go + +sudo: false + +matrix: + include: + - go: "1.9.x" + - go: "1.10.x" + - go: "1.11.x" + env: + - GO111MODULE=off + - go: "1.11.x" + env: + - GO111MODULE=on + - go: "tip" + env: + - GO111MODULE=off + - go: "tip" + env: + - GO111MODULE=on + allow_failures: + - go: "tip" + +install: make deps + +script: make ci-test diff --git a/vendor/github.com/markbates/inflect/LICENCE b/vendor/github.com/markbates/inflect/LICENCE new file mode 100644 index 0000000000..8a36b944a5 --- /dev/null +++ b/vendor/github.com/markbates/inflect/LICENCE @@ -0,0 +1,7 @@ +Copyright (c) 2011 Chris Farmiloe + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/markbates/inflect/Makefile b/vendor/github.com/markbates/inflect/Makefile new file mode 100644 index 0000000000..e0e2f3baa4 --- /dev/null +++ b/vendor/github.com/markbates/inflect/Makefile @@ -0,0 +1,55 @@ +TAGS ?= "sqlite" +GO_BIN ?= go + +install: + packr + $(GO_BIN) install -tags ${TAGS} -v . + make tidy + +tidy: +ifeq ($(GO111MODULE),on) + $(GO_BIN) mod tidy +else + echo skipping go mod tidy +endif + +deps: + $(GO_BIN) get github.com/gobuffalo/release + $(GO_BIN) get github.com/gobuffalo/packr/packr + $(GO_BIN) get -tags ${TAGS} -t ./... + make tidy + +build: + packr + $(GO_BIN) build -v . + make tidy + +test: + packr + $(GO_BIN) test -tags ${TAGS} ./... + make tidy + +ci-test: + $(GO_BIN) test -tags ${TAGS} -race ./... + make tidy + +lint: + gometalinter --vendor ./... --deadline=1m --skip=internal + make tidy + +update: + $(GO_BIN) get -u -tags ${TAGS} + make tidy + packr + make test + make install + make tidy + +release-test: + $(GO_BIN) test -tags ${TAGS} -race ./... + make tidy + +release: + make tidy + release -y -f version.go + make tidy diff --git a/vendor/github.com/markbates/inflect/README.md b/vendor/github.com/markbates/inflect/README.md new file mode 100644 index 0000000000..9b62b1d9a4 --- /dev/null +++ b/vendor/github.com/markbates/inflect/README.md @@ -0,0 +1,214 @@ +[![Build Status](https://travis-ci.org/markbates/inflect.svg?branch=master)](https://travis-ci.org/markbates/inflect) + +#### INSTALLATION + +go get github.com/markbates/inflect + +#### PACKAGE +package inflect + + +#### FUNCTIONS +```go +func AddAcronym(word string) +func AddHuman(suffix, replacement string) +func AddIrregular(singular, plural string) +func AddPlural(suffix, replacement string) +func AddSingular(suffix, replacement string) +func AddUncountable(word string) +func Asciify(word string) string +func Camelize(word string) string +func CamelizeDownFirst(word string) string +func Capitalize(word string) string +func Dasherize(word string) string +func ForeignKey(word string) string +func ForeignKeyCondensed(word string) string +func Humanize(word string) string +func Ordinalize(word string) string +func Parameterize(word string) string +func ParameterizeJoin(word, sep string) string +func Pluralize(word string) string +func Singularize(word string) string +func Tableize(word string) string +func Titleize(word string) string +func Typeify(word string) string +func Uncountables() map[string]bool +func Underscore(word string) string +``` + +#### TYPES +```go +type Rule struct { + // contains filtered or unexported fields +} +``` + +used by rulesets + +```go +type Ruleset struct { + // contains filtered or unexported fields +} +``` + +a Ruleset is the config of pluralization rules +you can extend the rules with the Add* methods + +``` +func NewDefaultRuleset() *Ruleset +``` +create a new ruleset and load it with the default +set of common English pluralization rules + +``` +func NewRuleset() *Ruleset +``` + +create a blank ruleset. Unless you are going to +build your own rules from scratch you probably +won't need this and can just use the defaultRuleset +via the global inflect.* methods + +``` +func (rs *Ruleset) AddAcronym(word string) +``` +if you use acronym you may need to add them to the ruleset +to prevent Underscored words of things like "HTML" coming out +as "h_t_m_l" + +``` +func (rs *Ruleset) AddHuman(suffix, replacement string) +``` + +Human rules are applied by humanize to show more friendly +versions of words + +``` +func (rs *Ruleset) AddIrregular(singular, plural string) +``` + +Add any inconsistent pluralizing/singularizing rules +to the set here. + +``` +func (rs *Ruleset) AddPlural(suffix, replacement string) +``` + +add a pluralization rule + +``` +func (rs *Ruleset) AddPluralExact(suffix, replacement string, exact bool) +``` + +add a pluralization rule with full string match + +``` +func (rs *Ruleset) AddSingular(suffix, replacement string) +``` + +add a singular rule + +``` +func (rs *Ruleset) AddSingularExact(suffix, replacement string, exact bool) +``` +same as AddSingular but you can set `exact` to force +a full string match + +``` +func (rs *Ruleset) AddUncountable(word string) +``` +add a word to this ruleset that has the same singular and plural form +for example: "rice" + +``` +func (rs *Ruleset) Asciify(word string) string +``` +transforms Latin characters like é -> e + +``` +func (rs *Ruleset) Camelize(word string) string +``` +"dino_party" -> "DinoParty" + +``` +func (rs *Ruleset) CamelizeDownFirst(word string) string +``` +same as Camelcase but with first letter downcased + +``` +func (rs *Ruleset) Capitalize(word string) string +``` +uppercase first character + +``` +func (rs *Ruleset) Dasherize(word string) string +``` +"SomeText" -> "some-text" + +``` +func (rs *Ruleset) ForeignKey(word string) string +``` +an underscored foreign key name "Person" -> "person_id" + +``` +func (rs *Ruleset) ForeignKeyCondensed(word string) string +``` +a foreign key (with an underscore) "Person" -> "personid" + +``` +func (rs *Ruleset) Humanize(word string) string +``` +First letter of sentence capitalized +Uses custom friendly replacements via AddHuman() + +``` +func (rs *Ruleset) Ordinalize(str string) string +``` +"1031" -> "1031st" + +``` +func (rs *Ruleset) Parameterize(word string) string +``` +param safe dasherized names like "my-param" + +``` +func (rs *Ruleset) ParameterizeJoin(word, sep string) string +``` +param safe dasherized names with custom separator + +``` +func (rs *Ruleset) Pluralize(word string) string +``` +returns the plural form of a singular word + +``` +func (rs *Ruleset) Singularize(word string) string +``` +returns the singular form of a plural word + +``` +func (rs *Ruleset) Tableize(word string) string +``` +Rails style pluralized table names: "SuperPerson" -> "super_people" + +``` +func (rs *Ruleset) Titleize(word string) string +``` +Capitalize every word in sentence "hello there" -> "Hello There" + +``` +func (rs *Ruleset) Typeify(word string) string +``` +"something_like_this" -> "SomethingLikeThis" + +``` +func (rs *Ruleset) Uncountables() map[string]bool +``` + +``` +func (rs *Ruleset) Underscore(word string) string +``` + +lowercase underscore version "BigBen" -> "big_ben" + + diff --git a/vendor/github.com/markbates/inflect/go.mod b/vendor/github.com/markbates/inflect/go.mod new file mode 100644 index 0000000000..3d7baa77f7 --- /dev/null +++ b/vendor/github.com/markbates/inflect/go.mod @@ -0,0 +1,6 @@ +module github.com/markbates/inflect + +require ( + github.com/gobuffalo/envy v1.6.5 + github.com/stretchr/testify v1.2.2 +) diff --git a/vendor/github.com/markbates/inflect/go.sum b/vendor/github.com/markbates/inflect/go.sum new file mode 100644 index 0000000000..6d42090d0a --- /dev/null +++ b/vendor/github.com/markbates/inflect/go.sum @@ -0,0 +1,10 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gobuffalo/envy v1.6.5 h1:X3is06x7v0nW2xiy2yFbbIjwHz57CD6z6MkvqULTCm8= +github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/vendor/github.com/markbates/inflect/helpers.go b/vendor/github.com/markbates/inflect/helpers.go new file mode 100644 index 0000000000..24050c70a0 --- /dev/null +++ b/vendor/github.com/markbates/inflect/helpers.go @@ -0,0 +1,19 @@ +package inflect + +//Helpers is a map of the helper names with its corresponding inflect function +var Helpers = map[string]interface{}{ + "asciffy": Asciify, + "camelize": Camelize, + "camelize_down_first": CamelizeDownFirst, + "capitalize": Capitalize, + "dasherize": Dasherize, + "humanize": Humanize, + "ordinalize": Ordinalize, + "parameterize": Parameterize, + "pluralize": Pluralize, + "pluralize_with_size": PluralizeWithSize, + "singularize": Singularize, + "tableize": Tableize, + "typeify": Typeify, + "underscore": Underscore, +} diff --git a/vendor/github.com/markbates/inflect/inflect.go b/vendor/github.com/markbates/inflect/inflect.go new file mode 100644 index 0000000000..9b6776c191 --- /dev/null +++ b/vendor/github.com/markbates/inflect/inflect.go @@ -0,0 +1,892 @@ +package inflect + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "regexp" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// baseAcronyms comes from https://en.wikipedia.org/wiki/List_of_information_technology_acronymss +const baseAcronyms = `JSON,JWT,ID,UUID,SQL,ACK,ACL,ADSL,AES,ANSI,API,ARP,ATM,BGP,BSS,CAT,CCITT,CHAP,CIDR,CIR,CLI,CPE,CPU,CRC,CRT,CSMA,CMOS,DCE,DEC,DES,DHCP,DNS,DRAM,DSL,DSLAM,DTE,DMI,EHA,EIA,EIGRP,EOF,ESS,FCC,FCS,FDDI,FTP,GBIC,gbps,GEPOF,HDLC,HTTP,HTTPS,IANA,ICMP,IDF,IDS,IEEE,IETF,IMAP,IP,IPS,ISDN,ISP,kbps,LACP,LAN,LAPB,LAPF,LLC,MAC,MAN,Mbps,MC,MDF,MIB,MoCA,MPLS,MTU,NAC,NAT,NBMA,NIC,NRZ,NRZI,NVRAM,OSI,OSPF,OUI,PAP,PAT,PC,PIM,PIM,PCM,PDU,POP3,POP,POTS,PPP,PPTP,PTT,PVST,RADIUS,RAM,RARP,RFC,RIP,RLL,ROM,RSTP,RTP,RCP,SDLC,SFD,SFP,SLARP,SLIP,SMTP,SNA,SNAP,SNMP,SOF,SRAM,SSH,SSID,STP,SYN,TDM,TFTP,TIA,TOFU,UDP,URL,URI,USB,UTP,VC,VLAN,VLSM,VPN,W3C,WAN,WEP,WiFi,WPA,WWW` + +// Rule used by rulesets +type Rule struct { + suffix string + replacement string + exact bool +} + +// Ruleset a Ruleset is the config of pluralization rules +// you can extend the rules with the Add* methods +type Ruleset struct { + uncountables map[string]bool + plurals []*Rule + singulars []*Rule + humans []*Rule + acronyms []*Rule +} + +// NewRuleset creates a blank ruleset. Unless you are going to +// build your own rules from scratch you probably +// won't need this and can just use the defaultRuleset +// via the global inflect.* methods +func NewRuleset() *Ruleset { + rs := new(Ruleset) + rs.uncountables = make(map[string]bool) + rs.plurals = make([]*Rule, 0) + rs.singulars = make([]*Rule, 0) + rs.humans = make([]*Rule, 0) + rs.acronyms = make([]*Rule, 0) + return rs +} + +// NewDefaultRuleset creates a new ruleset and load it with the default +// set of common English pluralization rules +func NewDefaultRuleset() *Ruleset { + rs := NewRuleset() + rs.AddPlural("movie", "movies") + rs.AddPlural("s", "s") + rs.AddPlural("testis", "testes") + rs.AddPlural("axis", "axes") + rs.AddPlural("octopus", "octopi") + rs.AddPlural("virus", "viri") + rs.AddPlural("octopi", "octopi") + rs.AddPlural("viri", "viri") + rs.AddPlural("alias", "aliases") + rs.AddPlural("status", "statuses") + rs.AddPlural("Status", "Statuses") + rs.AddPlural("campus", "campuses") + rs.AddPlural("bus", "buses") + rs.AddPlural("buffalo", "buffaloes") + rs.AddPlural("tomato", "tomatoes") + rs.AddPlural("tum", "ta") + rs.AddPlural("ium", "ia") + rs.AddPlural("ta", "ta") + rs.AddPlural("ia", "ia") + rs.AddPlural("sis", "ses") + rs.AddPlural("lf", "lves") + rs.AddPlural("rf", "rves") + rs.AddPlural("afe", "aves") + rs.AddPlural("bfe", "bves") + rs.AddPlural("cfe", "cves") + rs.AddPlural("dfe", "dves") + rs.AddPlural("efe", "eves") + rs.AddPlural("gfe", "gves") + rs.AddPlural("hfe", "hves") + rs.AddPlural("ife", "ives") + rs.AddPlural("jfe", "jves") + rs.AddPlural("kfe", "kves") + rs.AddPlural("lfe", "lves") + rs.AddPlural("mfe", "mves") + rs.AddPlural("nfe", "nves") + rs.AddPlural("ofe", "oves") + rs.AddPlural("pfe", "pves") + rs.AddPlural("qfe", "qves") + rs.AddPlural("rfe", "rves") + rs.AddPlural("sfe", "sves") + rs.AddPlural("tfe", "tves") + rs.AddPlural("ufe", "uves") + rs.AddPlural("vfe", "vves") + rs.AddPlural("wfe", "wves") + rs.AddPlural("xfe", "xves") + rs.AddPlural("yfe", "yves") + rs.AddPlural("zfe", "zves") + rs.AddPlural("hive", "hives") + rs.AddPlural("quy", "quies") + rs.AddPlural("by", "bies") + rs.AddPlural("cy", "cies") + rs.AddPlural("dy", "dies") + rs.AddPlural("fy", "fies") + rs.AddPlural("gy", "gies") + rs.AddPlural("hy", "hies") + rs.AddPlural("jy", "jies") + rs.AddPlural("ky", "kies") + rs.AddPlural("ly", "lies") + rs.AddPlural("my", "mies") + rs.AddPlural("ny", "nies") + rs.AddPlural("py", "pies") + rs.AddPlural("qy", "qies") + rs.AddPlural("ry", "ries") + rs.AddPlural("sy", "sies") + rs.AddPlural("ty", "ties") + rs.AddPlural("vy", "vies") + rs.AddPlural("wy", "wies") + rs.AddPlural("xy", "xies") + rs.AddPlural("zy", "zies") + rs.AddPlural("x", "xes") + rs.AddPlural("ch", "ches") + rs.AddPlural("ss", "sses") + rs.AddPlural("sh", "shes") + rs.AddPlural("matrix", "matrices") + rs.AddPlural("vertix", "vertices") + rs.AddPlural("indix", "indices") + rs.AddPlural("matrex", "matrices") + rs.AddPlural("vertex", "vertices") + rs.AddPlural("index", "indices") + rs.AddPlural("mouse", "mice") + rs.AddPlural("louse", "lice") + rs.AddPlural("mice", "mice") + rs.AddPlural("lice", "lice") + rs.AddPlural("ress", "resses") + rs.AddPluralExact("ox", "oxen", true) + rs.AddPluralExact("oxen", "oxen", true) + rs.AddPluralExact("quiz", "quizzes", true) + rs.AddSingular("s", "") + rs.AddSingular("ss", "ss") + rs.AddSingular("news", "news") + rs.AddSingular("ta", "tum") + rs.AddSingular("ia", "ium") + rs.AddSingular("analyses", "analysis") + rs.AddSingular("bases", "basis") + rs.AddSingularExact("basis", "basis", true) + rs.AddSingular("diagnoses", "diagnosis") + rs.AddSingularExact("diagnosis", "diagnosis", true) + rs.AddSingular("parentheses", "parenthesis") + rs.AddSingular("prognoses", "prognosis") + rs.AddSingular("synopses", "synopsis") + rs.AddSingular("theses", "thesis") + rs.AddSingular("analyses", "analysis") + rs.AddSingularExact("analysis", "analysis", true) + rs.AddSingular("ovies", "ovie") + rs.AddSingular("aves", "afe") + rs.AddSingular("bves", "bfe") + rs.AddSingular("cves", "cfe") + rs.AddSingular("dves", "dfe") + rs.AddSingular("eves", "efe") + rs.AddSingular("gves", "gfe") + rs.AddSingular("hves", "hfe") + rs.AddSingular("ives", "ife") + rs.AddSingular("jves", "jfe") + rs.AddSingular("kves", "kfe") + rs.AddSingular("lves", "lfe") + rs.AddSingular("mves", "mfe") + rs.AddSingular("nves", "nfe") + rs.AddSingular("oves", "ofe") + rs.AddSingular("pves", "pfe") + rs.AddSingular("qves", "qfe") + rs.AddSingular("rves", "rfe") + rs.AddSingular("sves", "sfe") + rs.AddSingular("tves", "tfe") + rs.AddSingular("uves", "ufe") + rs.AddSingular("vves", "vfe") + rs.AddSingular("wves", "wfe") + rs.AddSingular("xves", "xfe") + rs.AddSingular("yves", "yfe") + rs.AddSingular("zves", "zfe") + rs.AddSingular("hives", "hive") + rs.AddSingular("tives", "tive") + rs.AddSingular("lves", "lf") + rs.AddSingular("rves", "rf") + rs.AddSingular("quies", "quy") + rs.AddSingular("bies", "by") + rs.AddSingular("cies", "cy") + rs.AddSingular("dies", "dy") + rs.AddSingular("fies", "fy") + rs.AddSingular("gies", "gy") + rs.AddSingular("hies", "hy") + rs.AddSingular("jies", "jy") + rs.AddSingular("kies", "ky") + rs.AddSingular("lies", "ly") + rs.AddSingular("mies", "my") + rs.AddSingular("nies", "ny") + rs.AddSingular("pies", "py") + rs.AddSingular("qies", "qy") + rs.AddSingular("ries", "ry") + rs.AddSingular("sies", "sy") + rs.AddSingular("ties", "ty") + // rs.AddSingular("vies", "vy") + rs.AddSingular("wies", "wy") + rs.AddSingular("xies", "xy") + rs.AddSingular("zies", "zy") + rs.AddSingular("series", "series") + rs.AddSingular("xes", "x") + rs.AddSingular("ches", "ch") + rs.AddSingular("sses", "ss") + rs.AddSingular("shes", "sh") + rs.AddSingular("mice", "mouse") + rs.AddSingular("lice", "louse") + rs.AddSingular("buses", "bus") + rs.AddSingularExact("bus", "bus", true) + rs.AddSingular("oes", "o") + rs.AddSingular("shoes", "shoe") + rs.AddSingular("crises", "crisis") + rs.AddSingularExact("crisis", "crisis", true) + rs.AddSingular("axes", "axis") + rs.AddSingularExact("axis", "axis", true) + rs.AddSingular("testes", "testis") + rs.AddSingularExact("testis", "testis", true) + rs.AddSingular("octopi", "octopus") + rs.AddSingularExact("octopus", "octopus", true) + rs.AddSingular("viri", "virus") + rs.AddSingularExact("virus", "virus", true) + rs.AddSingular("statuses", "status") + rs.AddSingular("Statuses", "Status") + rs.AddSingular("campuses", "campus") + rs.AddSingularExact("status", "status", true) + rs.AddSingularExact("Status", "Status", true) + rs.AddSingularExact("campus", "campus", true) + rs.AddSingular("aliases", "alias") + rs.AddSingularExact("alias", "alias", true) + rs.AddSingularExact("oxen", "ox", true) + rs.AddSingular("vertices", "vertex") + rs.AddSingular("indices", "index") + rs.AddSingular("matrices", "matrix") + rs.AddSingularExact("quizzes", "quiz", true) + rs.AddSingular("databases", "database") + rs.AddSingular("resses", "ress") + rs.AddSingular("ress", "ress") + rs.AddIrregular("person", "people") + rs.AddIrregular("man", "men") + rs.AddIrregular("child", "children") + rs.AddIrregular("sex", "sexes") + rs.AddIrregular("move", "moves") + rs.AddIrregular("zombie", "zombies") + rs.AddIrregular("Status", "Statuses") + rs.AddIrregular("status", "statuses") + rs.AddIrregular("campus", "campuses") + rs.AddIrregular("human", "humans") + rs.AddUncountable("equipment") + rs.AddUncountable("information") + rs.AddUncountable("rice") + rs.AddUncountable("money") + rs.AddUncountable("species") + rs.AddUncountable("series") + rs.AddUncountable("fish") + rs.AddUncountable("sheep") + rs.AddUncountable("jeans") + rs.AddUncountable("police") + + acronyms := strings.Split(baseAcronyms, ",") + for _, acr := range acronyms { + rs.AddAcronym(acr) + } + + return rs +} + +// Uncountables returns a map of uncountables in the ruleset +func (rs *Ruleset) Uncountables() map[string]bool { + return rs.uncountables +} + +// AddPlural add a pluralization rule +func (rs *Ruleset) AddPlural(suffix, replacement string) { + rs.AddPluralExact(suffix, replacement, false) +} + +// AddPluralExact add a pluralization rule with full string match +func (rs *Ruleset) AddPluralExact(suffix, replacement string, exact bool) { + // remove uncountable + delete(rs.uncountables, suffix) + // create rule + r := new(Rule) + r.suffix = suffix + r.replacement = replacement + r.exact = exact + // prepend + rs.plurals = append([]*Rule{r}, rs.plurals...) +} + +// AddSingular add a singular rule +func (rs *Ruleset) AddSingular(suffix, replacement string) { + rs.AddSingularExact(suffix, replacement, false) +} + +// AddSingularExact same as AddSingular but you can set `exact` to force +// a full string match +func (rs *Ruleset) AddSingularExact(suffix, replacement string, exact bool) { + // remove from uncountable + delete(rs.uncountables, suffix) + // create rule + r := new(Rule) + r.suffix = suffix + r.replacement = replacement + r.exact = exact + rs.singulars = append([]*Rule{r}, rs.singulars...) +} + +// AddHuman Human rules are applied by humanize to show more friendly +// versions of words +func (rs *Ruleset) AddHuman(suffix, replacement string) { + r := new(Rule) + r.suffix = suffix + r.replacement = replacement + rs.humans = append([]*Rule{r}, rs.humans...) +} + +// AddIrregular Add any inconsistent pluralizing/singularizing rules +// to the set here. +func (rs *Ruleset) AddIrregular(singular, plural string) { + delete(rs.uncountables, singular) + delete(rs.uncountables, plural) + rs.AddPlural(singular, plural) + rs.AddPlural(plural, plural) + rs.AddSingular(plural, singular) +} + +// AddAcronym if you use acronym you may need to add them to the ruleset +// to prevent Underscored words of things like "HTML" coming out +// as "h_t_m_l" +func (rs *Ruleset) AddAcronym(word string) { + r := new(Rule) + r.suffix = word + r.replacement = rs.Titleize(strings.ToLower(word)) + rs.acronyms = append(rs.acronyms, r) +} + +// AddUncountable add a word to this ruleset that has the same singular and plural form +// for example: "rice" +func (rs *Ruleset) AddUncountable(word string) { + rs.uncountables[strings.ToLower(word)] = true +} + +func (rs *Ruleset) isUncountable(word string) bool { + // handle multiple words by using the last one + words := strings.Split(word, " ") + if _, exists := rs.uncountables[strings.ToLower(words[len(words)-1])]; exists { + return true + } + return false +} + +//isAcronym returns if a word is acronym or not. +func (rs *Ruleset) isAcronym(word string) bool { + for _, rule := range rs.acronyms { + if strings.ToUpper(rule.suffix) == strings.ToUpper(word) { + return true + } + } + + return false +} + +//PluralizeWithSize pluralize with taking number into account +func (rs *Ruleset) PluralizeWithSize(word string, size int) string { + if size == 1 { + return rs.Singularize(word) + } + return rs.Pluralize(word) +} + +// Pluralize returns the plural form of a singular word +func (rs *Ruleset) Pluralize(word string) string { + if len(word) == 0 { + return word + } + lWord := strings.ToLower(word) + if rs.isUncountable(lWord) { + return word + } + + var candidate string + for _, rule := range rs.plurals { + if rule.exact { + if lWord == rule.suffix { + // Capitalized word + if lWord[0] != word[0] && lWord[1:] == word[1:] { + return rs.Capitalize(rule.replacement) + } + return rule.replacement + } + continue + } + + if strings.EqualFold(word, rule.suffix) { + candidate = rule.replacement + } + + if strings.HasSuffix(word, rule.suffix) { + return replaceLast(word, rule.suffix, rule.replacement) + } + } + + if candidate != "" { + return candidate + } + return word + "s" +} + +//Singularize returns the singular form of a plural word +func (rs *Ruleset) Singularize(word string) string { + if len(word) <= 1 { + return word + } + lWord := strings.ToLower(word) + if rs.isUncountable(lWord) { + return word + } + + var candidate string + + for _, rule := range rs.singulars { + if rule.exact { + if lWord == rule.suffix { + // Capitalized word + if lWord[0] != word[0] && lWord[1:] == word[1:] { + return rs.Capitalize(rule.replacement) + } + return rule.replacement + } + continue + } + + if strings.EqualFold(word, rule.suffix) { + candidate = rule.replacement + } + + if strings.HasSuffix(word, rule.suffix) { + return replaceLast(word, rule.suffix, rule.replacement) + } + } + + if candidate != "" { + return candidate + } + + return word +} + +//Capitalize uppercase first character +func (rs *Ruleset) Capitalize(word string) string { + if rs.isAcronym(word) { + return strings.ToUpper(word) + } + return strings.ToUpper(word[:1]) + word[1:] +} + +//Camelize "dino_party" -> "DinoParty" +func (rs *Ruleset) Camelize(word string) string { + if rs.isAcronym(word) { + return strings.ToUpper(word) + } + words := splitAtCaseChangeWithTitlecase(word) + return strings.Join(words, "") +} + +//CamelizeDownFirst same as Camelcase but with first letter downcased +func (rs *Ruleset) CamelizeDownFirst(word string) string { + word = Camelize(word) + return strings.ToLower(word[:1]) + word[1:] +} + +//Titleize Capitalize every word in sentence "hello there" -> "Hello There" +func (rs *Ruleset) Titleize(word string) string { + words := splitAtCaseChangeWithTitlecase(word) + result := strings.Join(words, " ") + + var acronymWords []string + for index, word := range words { + if len(word) == 1 { + acronymWords = append(acronymWords, word) + } + + if len(word) > 1 || index == len(words)-1 || len(acronymWords) > 1 { + acronym := strings.Join(acronymWords, "") + if !rs.isAcronym(acronym) { + acronymWords = acronymWords[:len(acronymWords)] + continue + } + + result = strings.Replace(result, strings.Join(acronymWords, " "), acronym, 1) + acronymWords = []string{} + } + } + + return result +} + +func (rs *Ruleset) safeCaseAcronyms(word string) string { + // convert an acronym like HTML into Html + for _, rule := range rs.acronyms { + word = strings.Replace(word, rule.suffix, rule.replacement, -1) + } + return word +} + +func (rs *Ruleset) separatedWords(word, sep string) string { + word = rs.safeCaseAcronyms(word) + words := splitAtCaseChange(word) + return strings.Join(words, sep) +} + +//Underscore lowercase underscore version "BigBen" -> "big_ben" +func (rs *Ruleset) Underscore(word string) string { + return rs.separatedWords(word, "_") +} + +//Humanize First letter of sentence capitalized +// Uses custom friendly replacements via AddHuman() +func (rs *Ruleset) Humanize(word string) string { + word = replaceLast(word, "_id", "") // strip foreign key kinds + // replace and strings in humans list + for _, rule := range rs.humans { + word = strings.Replace(word, rule.suffix, rule.replacement, -1) + } + sentence := rs.separatedWords(word, " ") + + r, n := utf8.DecodeRuneInString(sentence) + return string(unicode.ToUpper(r)) + sentence[n:] +} + +//ForeignKey an underscored foreign key name "Person" -> "person_id" +func (rs *Ruleset) ForeignKey(word string) string { + return rs.Underscore(rs.Singularize(word)) + "_id" +} + +//ForeignKeyCondensed a foreign key (with an underscore) "Person" -> "personid" +func (rs *Ruleset) ForeignKeyCondensed(word string) string { + return rs.Underscore(word) + "id" +} + +//Tableize Rails style pluralized table names: "SuperPerson" -> "super_people" +func (rs *Ruleset) Tableize(word string) string { + return rs.Pluralize(rs.Underscore(rs.Typeify(word))) +} + +var notUrlSafe *regexp.Regexp = regexp.MustCompile(`[^\w\d\-_ ]`) + +//Parameterize param safe dasherized names like "my-param" +func (rs *Ruleset) Parameterize(word string) string { + return ParameterizeJoin(word, "-") +} + +//ParameterizeJoin param safe dasherized names with custom separator +func (rs *Ruleset) ParameterizeJoin(word, sep string) string { + word = strings.ToLower(word) + word = rs.Asciify(word) + word = notUrlSafe.ReplaceAllString(word, "") + word = strings.Replace(word, " ", sep, -1) + if len(sep) > 0 { + squash, err := regexp.Compile(sep + "+") + if err == nil { + word = squash.ReplaceAllString(word, sep) + } + } + word = strings.Trim(word, sep+" ") + return word +} + +var lookalikes = map[string]*regexp.Regexp{ + "A": regexp.MustCompile(`À|Á|Â|Ã|Ä|Å`), + "AE": regexp.MustCompile(`Æ`), + "C": regexp.MustCompile(`Ç`), + "E": regexp.MustCompile(`È|É|Ê|Ë`), + "G": regexp.MustCompile(`Ğ`), + "I": regexp.MustCompile(`Ì|Í|Î|Ï|İ`), + "N": regexp.MustCompile(`Ñ`), + "O": regexp.MustCompile(`Ò|Ó|Ô|Õ|Ö|Ø`), + "S": regexp.MustCompile(`Ş`), + "U": regexp.MustCompile(`Ù|Ú|Û|Ü`), + "Y": regexp.MustCompile(`Ý`), + "ss": regexp.MustCompile(`ß`), + "a": regexp.MustCompile(`à|á|â|ã|ä|å`), + "ae": regexp.MustCompile(`æ`), + "c": regexp.MustCompile(`ç`), + "e": regexp.MustCompile(`è|é|ê|ë`), + "g": regexp.MustCompile(`ğ`), + "i": regexp.MustCompile(`ì|í|î|ï|ı`), + "n": regexp.MustCompile(`ñ`), + "o": regexp.MustCompile(`ò|ó|ô|õ|ö|ø`), + "s": regexp.MustCompile(`ş`), + "u": regexp.MustCompile(`ù|ú|û|ü|ũ|ū|ŭ|ů|ű|ų`), + "y": regexp.MustCompile(`ý|ÿ`), +} + +//Asciify transforms Latin characters like é -> e +func (rs *Ruleset) Asciify(word string) string { + for repl, regex := range lookalikes { + word = regex.ReplaceAllString(word, repl) + } + return word +} + +var tablePrefix = regexp.MustCompile(`^[^.]*\.`) + +//Typeify "something_like_this" -> "SomethingLikeThis" +func (rs *Ruleset) Typeify(word string) string { + word = tablePrefix.ReplaceAllString(word, "") + return rs.Camelize(rs.Singularize(word)) +} + +//Dasherize "SomeText" -> "some-text" +func (rs *Ruleset) Dasherize(word string) string { + return rs.separatedWords(word, "-") +} + +//Ordinalize "1031" -> "1031st" +func (rs *Ruleset) Ordinalize(str string) string { + number, err := strconv.Atoi(str) + if err != nil { + return str + } + switch abs(number) % 100 { + case 11, 12, 13: + return fmt.Sprintf("%dth", number) + default: + switch abs(number) % 10 { + case 1: + return fmt.Sprintf("%dst", number) + case 2: + return fmt.Sprintf("%dnd", number) + case 3: + return fmt.Sprintf("%drd", number) + } + } + return fmt.Sprintf("%dth", number) +} + +//ForeignKeyToAttribute returns the attribute name from the foreign key +func (rs *Ruleset) ForeignKeyToAttribute(str string) string { + w := rs.Camelize(str) + if strings.HasSuffix(w, "Id") { + return strings.TrimSuffix(w, "Id") + "ID" + } + return w +} + +//LoadReader loads rules from io.Reader param +func (rs *Ruleset) LoadReader(r io.Reader) error { + m := map[string]string{} + err := json.NewDecoder(r).Decode(&m) + if err != nil { + return fmt.Errorf("could not decode inflection JSON from reader: %s", err) + } + for s, p := range m { + defaultRuleset.AddIrregular(s, p) + } + return nil +} + +///////////////////////////////////////// +// the default global ruleset +////////////////////////////////////////// + +var defaultRuleset *Ruleset + +//LoadReader loads rules from io.Reader param +func LoadReader(r io.Reader) error { + return defaultRuleset.LoadReader(r) +} + +func init() { + defaultRuleset = NewDefaultRuleset() + + pwd, _ := os.Getwd() + cfg := filepath.Join(pwd, "inflections.json") + if p := os.Getenv("INFLECT_PATH"); p != "" { + cfg = p + } + if _, err := os.Stat(cfg); err == nil { + b, err := ioutil.ReadFile(cfg) + if err != nil { + fmt.Printf("could not read inflection file %s (%s)\n", cfg, err) + return + } + if err = defaultRuleset.LoadReader(bytes.NewReader(b)); err != nil { + fmt.Println(err) + } + } +} + +//Uncountables returns a list of uncountables rules +func Uncountables() map[string]bool { + return defaultRuleset.Uncountables() +} + +//AddPlural adds plural to the ruleset +func AddPlural(suffix, replacement string) { + defaultRuleset.AddPlural(suffix, replacement) +} + +//AddSingular adds singular to the ruleset +func AddSingular(suffix, replacement string) { + defaultRuleset.AddSingular(suffix, replacement) +} + +//AddHuman adds human +func AddHuman(suffix, replacement string) { + defaultRuleset.AddHuman(suffix, replacement) +} + +func AddIrregular(singular, plural string) { + defaultRuleset.AddIrregular(singular, plural) +} + +func AddAcronym(word string) { + defaultRuleset.AddAcronym(word) +} + +func AddUncountable(word string) { + defaultRuleset.AddUncountable(word) +} + +func Pluralize(word string) string { + return defaultRuleset.Pluralize(word) +} + +func PluralizeWithSize(word string, size int) string { + return defaultRuleset.PluralizeWithSize(word, size) +} + +func Singularize(word string) string { + return defaultRuleset.Singularize(word) +} + +func Capitalize(word string) string { + return defaultRuleset.Capitalize(word) +} + +func Camelize(word string) string { + return defaultRuleset.Camelize(word) +} + +func CamelizeDownFirst(word string) string { + return defaultRuleset.CamelizeDownFirst(word) +} + +func Titleize(word string) string { + return defaultRuleset.Titleize(word) +} + +func Underscore(word string) string { + return defaultRuleset.Underscore(word) +} + +func Humanize(word string) string { + return defaultRuleset.Humanize(word) +} + +func ForeignKey(word string) string { + return defaultRuleset.ForeignKey(word) +} + +func ForeignKeyCondensed(word string) string { + return defaultRuleset.ForeignKeyCondensed(word) +} + +func Tableize(word string) string { + return defaultRuleset.Tableize(word) +} + +func Parameterize(word string) string { + return defaultRuleset.Parameterize(word) +} + +func ParameterizeJoin(word, sep string) string { + return defaultRuleset.ParameterizeJoin(word, sep) +} + +func Typeify(word string) string { + return defaultRuleset.Typeify(word) +} + +func Dasherize(word string) string { + return defaultRuleset.Dasherize(word) +} + +func Ordinalize(word string) string { + return defaultRuleset.Ordinalize(word) +} + +func Asciify(word string) string { + return defaultRuleset.Asciify(word) +} + +func ForeignKeyToAttribute(word string) string { + return defaultRuleset.ForeignKeyToAttribute(word) +} + +// helper funcs + +func reverse(s string) string { + o := make([]rune, utf8.RuneCountInString(s)) + i := len(o) + for _, c := range s { + i-- + o[i] = c + } + return string(o) +} + +func isSpacerChar(c rune) bool { + switch { + case c == rune("_"[0]): + return true + case c == rune(" "[0]): + return true + case c == rune(":"[0]): + return true + case c == rune("-"[0]): + return true + } + return false +} + +func splitAtCaseChange(s string) []string { + words := make([]string, 0) + word := make([]rune, 0) + for _, c := range s { + spacer := isSpacerChar(c) + if len(word) > 0 { + if unicode.IsUpper(c) || spacer { + words = append(words, string(word)) + word = make([]rune, 0) + } + } + if !spacer { + word = append(word, unicode.ToLower(c)) + } + } + words = append(words, string(word)) + return words +} + +func splitAtCaseChangeWithTitlecase(s string) []string { + words := make([]string, 0) + word := make([]rune, 0) + + for _, c := range s { + spacer := isSpacerChar(c) + if len(word) > 0 { + if unicode.IsUpper(c) || spacer { + words = append(words, string(word)) + word = make([]rune, 0) + } + } + if !spacer { + if len(word) > 0 { + word = append(word, unicode.ToLower(c)) + } else { + word = append(word, unicode.ToUpper(c)) + } + } + } + + words = append(words, string(word)) + return words +} + +func replaceLast(s, match, repl string) string { + // reverse strings + srev := reverse(s) + mrev := reverse(match) + rrev := reverse(repl) + // match first and reverse back + return reverse(strings.Replace(srev, mrev, rrev, 1)) +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} diff --git a/vendor/github.com/markbates/inflect/inflections.json b/vendor/github.com/markbates/inflect/inflections.json new file mode 100644 index 0000000000..5fd3cbf279 --- /dev/null +++ b/vendor/github.com/markbates/inflect/inflections.json @@ -0,0 +1,4 @@ +{ + "feedback": "feedback", + "buffalo!": "buffalos!" +} diff --git a/vendor/github.com/markbates/inflect/name.go b/vendor/github.com/markbates/inflect/name.go new file mode 100644 index 0000000000..e6863e28a6 --- /dev/null +++ b/vendor/github.com/markbates/inflect/name.go @@ -0,0 +1,163 @@ +package inflect + +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/gobuffalo/envy" +) + +// Name is a string that represents the "name" of a thing, like an app, model, etc... +type Name string + +// Title version of a name. ie. "foo_bar" => "Foo Bar" +func (n Name) Title() string { + x := strings.Split(string(n), "/") + for i, s := range x { + x[i] = Titleize(s) + } + + return strings.Join(x, " ") +} + +// Underscore version of a name. ie. "FooBar" => "foo_bar" +func (n Name) Underscore() string { + w := string(n) + if strings.ToUpper(w) == w { + return strings.ToLower(w) + } + return Underscore(w) +} + +// Plural version of a name +func (n Name) Plural() string { + return Pluralize(string(n)) +} + +// Singular version of a name +func (n Name) Singular() string { + return Singularize(string(n)) +} + +// Camel version of a name +func (n Name) Camel() string { + c := Camelize(string(n)) + if strings.HasSuffix(c, "Id") { + c = strings.TrimSuffix(c, "Id") + c += "ID" + } + return c +} + +// Model version of a name. ie. "user" => "User" +func (n Name) Model() string { + x := strings.Split(string(n), "/") + for i, s := range x { + x[i] = Camelize(Singularize(s)) + } + + return strings.Join(x, "") +} + +// Resource version of a name +func (n Name) Resource() string { + name := n.Underscore() + x := strings.FieldsFunc(name, func(r rune) bool { + return r == '_' || r == '/' + }) + + for i, w := range x { + if i == len(x)-1 { + x[i] = Camelize(Pluralize(strings.ToLower(w))) + continue + } + + x[i] = Camelize(w) + } + + return strings.Join(x, "") +} + +// ModelPlural version of a name. ie. "user" => "Users" +func (n Name) ModelPlural() string { + return Camelize(Pluralize(n.Model())) +} + +// File version of a name +func (n Name) File() string { + return Underscore(Camelize(string(n))) +} + +// Table version of a name +func (n Name) Table() string { + return Underscore(Pluralize(string(n))) +} + +// UnderSingular version of a name +func (n Name) UnderSingular() string { + return Underscore(Singularize(string(n))) +} + +// PluralCamel version of a name +func (n Name) PluralCamel() string { + return Pluralize(Camelize(string(n))) +} + +// PluralUnder version of a name +func (n Name) PluralUnder() string { + return Pluralize(Underscore(string(n))) +} + +// URL version of a name +func (n Name) URL() string { + return n.PluralUnder() +} + +// CamelSingular version of a name +func (n Name) CamelSingular() string { + return Camelize(Singularize(string(n))) +} + +// VarCaseSingular version of a name. ie. "FooBar" => "fooBar" +func (n Name) VarCaseSingular() string { + return CamelizeDownFirst(Singularize(Underscore(n.Resource()))) +} + +// VarCasePlural version of a name. ie. "FooBar" => "fooBar" +func (n Name) VarCasePlural() string { + return CamelizeDownFirst(n.Resource()) +} + +// Lower case version of a string +func (n Name) Lower() string { + return strings.ToLower(string(n)) +} + +// ParamID returns foo_bar_id +func (n Name) ParamID() string { + return fmt.Sprintf("%s_id", strings.Replace(n.UnderSingular(), "/", "_", -1)) +} + +// Package returns go package +func (n Name) Package() string { + key := string(n) + + for _, gp := range envy.GoPaths() { + key = strings.TrimPrefix(key, filepath.Join(gp, "src")) + key = strings.TrimPrefix(key, gp) + } + key = strings.TrimPrefix(key, string(filepath.Separator)) + + key = strings.Replace(key, "\\", "/", -1) + return key +} + +// Char returns first character in lower case, this is useful for methods inside a struct. +func (n Name) Char() string { + return strings.ToLower(string(n[0])) +} + +func (n Name) String() string { + return string(n) +} diff --git a/vendor/github.com/markbates/inflect/shoulders.md b/vendor/github.com/markbates/inflect/shoulders.md new file mode 100644 index 0000000000..619e7892f7 --- /dev/null +++ b/vendor/github.com/markbates/inflect/shoulders.md @@ -0,0 +1,12 @@ +# github.com/markbates/inflect Stands on the Shoulders of Giants + +github.com/markbates/inflect does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants this project would not be possible. Please make sure to check them out and thank them for all of their hard work. + +Thank you to the following **GIANTS**: + + +* [github.com/gobuffalo/envy](https://godoc.org/github.com/gobuffalo/envy) + +* [github.com/joho/godotenv](https://godoc.org/github.com/joho/godotenv) + +* [github.com/markbates/inflect](https://godoc.org/github.com/markbates/inflect) diff --git a/vendor/github.com/markbates/inflect/version.go b/vendor/github.com/markbates/inflect/version.go new file mode 100644 index 0000000000..a167449841 --- /dev/null +++ b/vendor/github.com/markbates/inflect/version.go @@ -0,0 +1,3 @@ +package inflect + +const Version = "v1.0.4" diff --git a/vendor/github.com/robfig/cron/.gitignore b/vendor/github.com/robfig/cron/.gitignore new file mode 100644 index 0000000000..00268614f0 --- /dev/null +++ b/vendor/github.com/robfig/cron/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/robfig/cron/.travis.yml b/vendor/github.com/robfig/cron/.travis.yml new file mode 100644 index 0000000000..4f2ee4d973 --- /dev/null +++ b/vendor/github.com/robfig/cron/.travis.yml @@ -0,0 +1 @@ +language: go diff --git a/vendor/github.com/robfig/cron/LICENSE b/vendor/github.com/robfig/cron/LICENSE new file mode 100644 index 0000000000..3a0f627ffe --- /dev/null +++ b/vendor/github.com/robfig/cron/LICENSE @@ -0,0 +1,21 @@ +Copyright (C) 2012 Rob Figueiredo +All Rights Reserved. + +MIT LICENSE + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/robfig/cron/README.md b/vendor/github.com/robfig/cron/README.md new file mode 100644 index 0000000000..ec40c95fcb --- /dev/null +++ b/vendor/github.com/robfig/cron/README.md @@ -0,0 +1,6 @@ +[![GoDoc](http://godoc.org/github.com/robfig/cron?status.png)](http://godoc.org/github.com/robfig/cron) +[![Build Status](https://travis-ci.org/robfig/cron.svg?branch=master)](https://travis-ci.org/robfig/cron) + +# cron + +Documentation here: https://godoc.org/github.com/robfig/cron diff --git a/vendor/github.com/robfig/cron/constantdelay.go b/vendor/github.com/robfig/cron/constantdelay.go new file mode 100644 index 0000000000..cd6e7b1be9 --- /dev/null +++ b/vendor/github.com/robfig/cron/constantdelay.go @@ -0,0 +1,27 @@ +package cron + +import "time" + +// ConstantDelaySchedule represents a simple recurring duty cycle, e.g. "Every 5 minutes". +// It does not support jobs more frequent than once a second. +type ConstantDelaySchedule struct { + Delay time.Duration +} + +// Every returns a crontab Schedule that activates once every duration. +// Delays of less than a second are not supported (will round up to 1 second). +// Any fields less than a Second are truncated. +func Every(duration time.Duration) ConstantDelaySchedule { + if duration < time.Second { + duration = time.Second + } + return ConstantDelaySchedule{ + Delay: duration - time.Duration(duration.Nanoseconds())%time.Second, + } +} + +// Next returns the next time this should be run. +// This rounds so that the next activation time will be on the second. +func (schedule ConstantDelaySchedule) Next(t time.Time) time.Time { + return t.Add(schedule.Delay - time.Duration(t.Nanosecond())*time.Nanosecond) +} diff --git a/vendor/github.com/robfig/cron/cron.go b/vendor/github.com/robfig/cron/cron.go new file mode 100644 index 0000000000..2318aeb2e7 --- /dev/null +++ b/vendor/github.com/robfig/cron/cron.go @@ -0,0 +1,259 @@ +package cron + +import ( + "log" + "runtime" + "sort" + "time" +) + +// Cron keeps track of any number of entries, invoking the associated func as +// specified by the schedule. It may be started, stopped, and the entries may +// be inspected while running. +type Cron struct { + entries []*Entry + stop chan struct{} + add chan *Entry + snapshot chan []*Entry + running bool + ErrorLog *log.Logger + location *time.Location +} + +// Job is an interface for submitted cron jobs. +type Job interface { + Run() +} + +// The Schedule describes a job's duty cycle. +type Schedule interface { + // Return the next activation time, later than the given time. + // Next is invoked initially, and then each time the job is run. + Next(time.Time) time.Time +} + +// Entry consists of a schedule and the func to execute on that schedule. +type Entry struct { + // The schedule on which this job should be run. + Schedule Schedule + + // The next time the job will run. This is the zero time if Cron has not been + // started or this entry's schedule is unsatisfiable + Next time.Time + + // The last time this job was run. This is the zero time if the job has never + // been run. + Prev time.Time + + // The Job to run. + Job Job +} + +// byTime is a wrapper for sorting the entry array by time +// (with zero time at the end). +type byTime []*Entry + +func (s byTime) Len() int { return len(s) } +func (s byTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s byTime) Less(i, j int) bool { + // Two zero times should return false. + // Otherwise, zero is "greater" than any other time. + // (To sort it at the end of the list.) + if s[i].Next.IsZero() { + return false + } + if s[j].Next.IsZero() { + return true + } + return s[i].Next.Before(s[j].Next) +} + +// New returns a new Cron job runner, in the Local time zone. +func New() *Cron { + return NewWithLocation(time.Now().Location()) +} + +// NewWithLocation returns a new Cron job runner. +func NewWithLocation(location *time.Location) *Cron { + return &Cron{ + entries: nil, + add: make(chan *Entry), + stop: make(chan struct{}), + snapshot: make(chan []*Entry), + running: false, + ErrorLog: nil, + location: location, + } +} + +// A wrapper that turns a func() into a cron.Job +type FuncJob func() + +func (f FuncJob) Run() { f() } + +// AddFunc adds a func to the Cron to be run on the given schedule. +func (c *Cron) AddFunc(spec string, cmd func()) error { + return c.AddJob(spec, FuncJob(cmd)) +} + +// AddJob adds a Job to the Cron to be run on the given schedule. +func (c *Cron) AddJob(spec string, cmd Job) error { + schedule, err := Parse(spec) + if err != nil { + return err + } + c.Schedule(schedule, cmd) + return nil +} + +// Schedule adds a Job to the Cron to be run on the given schedule. +func (c *Cron) Schedule(schedule Schedule, cmd Job) { + entry := &Entry{ + Schedule: schedule, + Job: cmd, + } + if !c.running { + c.entries = append(c.entries, entry) + return + } + + c.add <- entry +} + +// Entries returns a snapshot of the cron entries. +func (c *Cron) Entries() []*Entry { + if c.running { + c.snapshot <- nil + x := <-c.snapshot + return x + } + return c.entrySnapshot() +} + +// Location gets the time zone location +func (c *Cron) Location() *time.Location { + return c.location +} + +// Start the cron scheduler in its own go-routine, or no-op if already started. +func (c *Cron) Start() { + if c.running { + return + } + c.running = true + go c.run() +} + +// Run the cron scheduler, or no-op if already running. +func (c *Cron) Run() { + if c.running { + return + } + c.running = true + c.run() +} + +func (c *Cron) runWithRecovery(j Job) { + defer func() { + if r := recover(); r != nil { + const size = 64 << 10 + buf := make([]byte, size) + buf = buf[:runtime.Stack(buf, false)] + c.logf("cron: panic running job: %v\n%s", r, buf) + } + }() + j.Run() +} + +// Run the scheduler. this is private just due to the need to synchronize +// access to the 'running' state variable. +func (c *Cron) run() { + // Figure out the next activation times for each entry. + now := c.now() + for _, entry := range c.entries { + entry.Next = entry.Schedule.Next(now) + } + + for { + // Determine the next entry to run. + sort.Sort(byTime(c.entries)) + + var timer *time.Timer + if len(c.entries) == 0 || c.entries[0].Next.IsZero() { + // If there are no entries yet, just sleep - it still handles new entries + // and stop requests. + timer = time.NewTimer(100000 * time.Hour) + } else { + timer = time.NewTimer(c.entries[0].Next.Sub(now)) + } + + for { + select { + case now = <-timer.C: + now = now.In(c.location) + // Run every entry whose next time was less than now + for _, e := range c.entries { + if e.Next.After(now) || e.Next.IsZero() { + break + } + go c.runWithRecovery(e.Job) + e.Prev = e.Next + e.Next = e.Schedule.Next(now) + } + + case newEntry := <-c.add: + timer.Stop() + now = c.now() + newEntry.Next = newEntry.Schedule.Next(now) + c.entries = append(c.entries, newEntry) + + case <-c.snapshot: + c.snapshot <- c.entrySnapshot() + continue + + case <-c.stop: + timer.Stop() + return + } + + break + } + } +} + +// Logs an error to stderr or to the configured error log +func (c *Cron) logf(format string, args ...interface{}) { + if c.ErrorLog != nil { + c.ErrorLog.Printf(format, args...) + } else { + log.Printf(format, args...) + } +} + +// Stop stops the cron scheduler if it is running; otherwise it does nothing. +func (c *Cron) Stop() { + if !c.running { + return + } + c.stop <- struct{}{} + c.running = false +} + +// entrySnapshot returns a copy of the current cron entry list. +func (c *Cron) entrySnapshot() []*Entry { + entries := []*Entry{} + for _, e := range c.entries { + entries = append(entries, &Entry{ + Schedule: e.Schedule, + Next: e.Next, + Prev: e.Prev, + Job: e.Job, + }) + } + return entries +} + +// now returns current time in c location +func (c *Cron) now() time.Time { + return time.Now().In(c.location) +} diff --git a/vendor/github.com/robfig/cron/doc.go b/vendor/github.com/robfig/cron/doc.go new file mode 100644 index 0000000000..d02ec2f3b5 --- /dev/null +++ b/vendor/github.com/robfig/cron/doc.go @@ -0,0 +1,129 @@ +/* +Package cron implements a cron spec parser and job runner. + +Usage + +Callers may register Funcs to be invoked on a given schedule. Cron will run +them in their own goroutines. + + c := cron.New() + c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") }) + c.AddFunc("@hourly", func() { fmt.Println("Every hour") }) + c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") }) + c.Start() + .. + // Funcs are invoked in their own goroutine, asynchronously. + ... + // Funcs may also be added to a running Cron + c.AddFunc("@daily", func() { fmt.Println("Every day") }) + .. + // Inspect the cron job entries' next and previous run times. + inspect(c.Entries()) + .. + c.Stop() // Stop the scheduler (does not stop any jobs already running). + +CRON Expression Format + +A cron expression represents a set of times, using 6 space-separated fields. + + Field name | Mandatory? | Allowed values | Allowed special characters + ---------- | ---------- | -------------- | -------------------------- + Seconds | Yes | 0-59 | * / , - + Minutes | Yes | 0-59 | * / , - + Hours | Yes | 0-23 | * / , - + Day of month | Yes | 1-31 | * / , - ? + Month | Yes | 1-12 or JAN-DEC | * / , - + Day of week | Yes | 0-6 or SUN-SAT | * / , - ? + +Note: Month and Day-of-week field values are case insensitive. "SUN", "Sun", +and "sun" are equally accepted. + +Special Characters + +Asterisk ( * ) + +The asterisk indicates that the cron expression will match for all values of the +field; e.g., using an asterisk in the 5th field (month) would indicate every +month. + +Slash ( / ) + +Slashes are used to describe increments of ranges. For example 3-59/15 in the +1st field (minutes) would indicate the 3rd minute of the hour and every 15 +minutes thereafter. The form "*\/..." is equivalent to the form "first-last/...", +that is, an increment over the largest possible range of the field. The form +"N/..." is accepted as meaning "N-MAX/...", that is, starting at N, use the +increment until the end of that specific range. It does not wrap around. + +Comma ( , ) + +Commas are used to separate items of a list. For example, using "MON,WED,FRI" in +the 5th field (day of week) would mean Mondays, Wednesdays and Fridays. + +Hyphen ( - ) + +Hyphens are used to define ranges. For example, 9-17 would indicate every +hour between 9am and 5pm inclusive. + +Question mark ( ? ) + +Question mark may be used instead of '*' for leaving either day-of-month or +day-of-week blank. + +Predefined schedules + +You may use one of several pre-defined schedules in place of a cron expression. + + Entry | Description | Equivalent To + ----- | ----------- | ------------- + @yearly (or @annually) | Run once a year, midnight, Jan. 1st | 0 0 0 1 1 * + @monthly | Run once a month, midnight, first of month | 0 0 0 1 * * + @weekly | Run once a week, midnight between Sat/Sun | 0 0 0 * * 0 + @daily (or @midnight) | Run once a day, midnight | 0 0 0 * * * + @hourly | Run once an hour, beginning of hour | 0 0 * * * * + +Intervals + +You may also schedule a job to execute at fixed intervals, starting at the time it's added +or cron is run. This is supported by formatting the cron spec like this: + + @every + +where "duration" is a string accepted by time.ParseDuration +(http://golang.org/pkg/time/#ParseDuration). + +For example, "@every 1h30m10s" would indicate a schedule that activates after +1 hour, 30 minutes, 10 seconds, and then every interval after that. + +Note: The interval does not take the job runtime into account. For example, +if a job takes 3 minutes to run, and it is scheduled to run every 5 minutes, +it will have only 2 minutes of idle time between each run. + +Time zones + +All interpretation and scheduling is done in the machine's local time zone (as +provided by the Go time package (http://www.golang.org/pkg/time). + +Be aware that jobs scheduled during daylight-savings leap-ahead transitions will +not be run! + +Thread safety + +Since the Cron service runs concurrently with the calling code, some amount of +care must be taken to ensure proper synchronization. + +All cron methods are designed to be correctly synchronized as long as the caller +ensures that invocations have a clear happens-before ordering between them. + +Implementation + +Cron entries are stored in an array, sorted by their next activation time. Cron +sleeps until the next job is due to be run. + +Upon waking: + - it runs each entry that is active on that second + - it calculates the next run times for the jobs that were run + - it re-sorts the array of entries by next activation time. + - it goes to sleep until the soonest job. +*/ +package cron diff --git a/vendor/github.com/robfig/cron/parser.go b/vendor/github.com/robfig/cron/parser.go new file mode 100644 index 0000000000..a5e83c0a8d --- /dev/null +++ b/vendor/github.com/robfig/cron/parser.go @@ -0,0 +1,380 @@ +package cron + +import ( + "fmt" + "math" + "strconv" + "strings" + "time" +) + +// Configuration options for creating a parser. Most options specify which +// fields should be included, while others enable features. If a field is not +// included the parser will assume a default value. These options do not change +// the order fields are parse in. +type ParseOption int + +const ( + Second ParseOption = 1 << iota // Seconds field, default 0 + Minute // Minutes field, default 0 + Hour // Hours field, default 0 + Dom // Day of month field, default * + Month // Month field, default * + Dow // Day of week field, default * + DowOptional // Optional day of week field, default * + Descriptor // Allow descriptors such as @monthly, @weekly, etc. +) + +var places = []ParseOption{ + Second, + Minute, + Hour, + Dom, + Month, + Dow, +} + +var defaults = []string{ + "0", + "0", + "0", + "*", + "*", + "*", +} + +// A custom Parser that can be configured. +type Parser struct { + options ParseOption + optionals int +} + +// Creates a custom Parser with custom options. +// +// // Standard parser without descriptors +// specParser := NewParser(Minute | Hour | Dom | Month | Dow) +// sched, err := specParser.Parse("0 0 15 */3 *") +// +// // Same as above, just excludes time fields +// subsParser := NewParser(Dom | Month | Dow) +// sched, err := specParser.Parse("15 */3 *") +// +// // Same as above, just makes Dow optional +// subsParser := NewParser(Dom | Month | DowOptional) +// sched, err := specParser.Parse("15 */3") +// +func NewParser(options ParseOption) Parser { + optionals := 0 + if options&DowOptional > 0 { + options |= Dow + optionals++ + } + return Parser{options, optionals} +} + +// Parse returns a new crontab schedule representing the given spec. +// It returns a descriptive error if the spec is not valid. +// It accepts crontab specs and features configured by NewParser. +func (p Parser) Parse(spec string) (Schedule, error) { + if len(spec) == 0 { + return nil, fmt.Errorf("Empty spec string") + } + if spec[0] == '@' && p.options&Descriptor > 0 { + return parseDescriptor(spec) + } + + // Figure out how many fields we need + max := 0 + for _, place := range places { + if p.options&place > 0 { + max++ + } + } + min := max - p.optionals + + // Split fields on whitespace + fields := strings.Fields(spec) + + // Validate number of fields + if count := len(fields); count < min || count > max { + if min == max { + return nil, fmt.Errorf("Expected exactly %d fields, found %d: %s", min, count, spec) + } + return nil, fmt.Errorf("Expected %d to %d fields, found %d: %s", min, max, count, spec) + } + + // Fill in missing fields + fields = expandFields(fields, p.options) + + var err error + field := func(field string, r bounds) uint64 { + if err != nil { + return 0 + } + var bits uint64 + bits, err = getField(field, r) + return bits + } + + var ( + second = field(fields[0], seconds) + minute = field(fields[1], minutes) + hour = field(fields[2], hours) + dayofmonth = field(fields[3], dom) + month = field(fields[4], months) + dayofweek = field(fields[5], dow) + ) + if err != nil { + return nil, err + } + + return &SpecSchedule{ + Second: second, + Minute: minute, + Hour: hour, + Dom: dayofmonth, + Month: month, + Dow: dayofweek, + }, nil +} + +func expandFields(fields []string, options ParseOption) []string { + n := 0 + count := len(fields) + expFields := make([]string, len(places)) + copy(expFields, defaults) + for i, place := range places { + if options&place > 0 { + expFields[i] = fields[n] + n++ + } + if n == count { + break + } + } + return expFields +} + +var standardParser = NewParser( + Minute | Hour | Dom | Month | Dow | Descriptor, +) + +// ParseStandard returns a new crontab schedule representing the given standardSpec +// (https://en.wikipedia.org/wiki/Cron). It differs from Parse requiring to always +// pass 5 entries representing: minute, hour, day of month, month and day of week, +// in that order. It returns a descriptive error if the spec is not valid. +// +// It accepts +// - Standard crontab specs, e.g. "* * * * ?" +// - Descriptors, e.g. "@midnight", "@every 1h30m" +func ParseStandard(standardSpec string) (Schedule, error) { + return standardParser.Parse(standardSpec) +} + +var defaultParser = NewParser( + Second | Minute | Hour | Dom | Month | DowOptional | Descriptor, +) + +// Parse returns a new crontab schedule representing the given spec. +// It returns a descriptive error if the spec is not valid. +// +// It accepts +// - Full crontab specs, e.g. "* * * * * ?" +// - Descriptors, e.g. "@midnight", "@every 1h30m" +func Parse(spec string) (Schedule, error) { + return defaultParser.Parse(spec) +} + +// getField returns an Int with the bits set representing all of the times that +// the field represents or error parsing field value. A "field" is a comma-separated +// list of "ranges". +func getField(field string, r bounds) (uint64, error) { + var bits uint64 + ranges := strings.FieldsFunc(field, func(r rune) bool { return r == ',' }) + for _, expr := range ranges { + bit, err := getRange(expr, r) + if err != nil { + return bits, err + } + bits |= bit + } + return bits, nil +} + +// getRange returns the bits indicated by the given expression: +// number | number "-" number [ "/" number ] +// or error parsing range. +func getRange(expr string, r bounds) (uint64, error) { + var ( + start, end, step uint + rangeAndStep = strings.Split(expr, "/") + lowAndHigh = strings.Split(rangeAndStep[0], "-") + singleDigit = len(lowAndHigh) == 1 + err error + ) + + var extra uint64 + if lowAndHigh[0] == "*" || lowAndHigh[0] == "?" { + start = r.min + end = r.max + extra = starBit + } else { + start, err = parseIntOrName(lowAndHigh[0], r.names) + if err != nil { + return 0, err + } + switch len(lowAndHigh) { + case 1: + end = start + case 2: + end, err = parseIntOrName(lowAndHigh[1], r.names) + if err != nil { + return 0, err + } + default: + return 0, fmt.Errorf("Too many hyphens: %s", expr) + } + } + + switch len(rangeAndStep) { + case 1: + step = 1 + case 2: + step, err = mustParseInt(rangeAndStep[1]) + if err != nil { + return 0, err + } + + // Special handling: "N/step" means "N-max/step". + if singleDigit { + end = r.max + } + default: + return 0, fmt.Errorf("Too many slashes: %s", expr) + } + + if start < r.min { + return 0, fmt.Errorf("Beginning of range (%d) below minimum (%d): %s", start, r.min, expr) + } + if end > r.max { + return 0, fmt.Errorf("End of range (%d) above maximum (%d): %s", end, r.max, expr) + } + if start > end { + return 0, fmt.Errorf("Beginning of range (%d) beyond end of range (%d): %s", start, end, expr) + } + if step == 0 { + return 0, fmt.Errorf("Step of range should be a positive number: %s", expr) + } + + return getBits(start, end, step) | extra, nil +} + +// parseIntOrName returns the (possibly-named) integer contained in expr. +func parseIntOrName(expr string, names map[string]uint) (uint, error) { + if names != nil { + if namedInt, ok := names[strings.ToLower(expr)]; ok { + return namedInt, nil + } + } + return mustParseInt(expr) +} + +// mustParseInt parses the given expression as an int or returns an error. +func mustParseInt(expr string) (uint, error) { + num, err := strconv.Atoi(expr) + if err != nil { + return 0, fmt.Errorf("Failed to parse int from %s: %s", expr, err) + } + if num < 0 { + return 0, fmt.Errorf("Negative number (%d) not allowed: %s", num, expr) + } + + return uint(num), nil +} + +// getBits sets all bits in the range [min, max], modulo the given step size. +func getBits(min, max, step uint) uint64 { + var bits uint64 + + // If step is 1, use shifts. + if step == 1 { + return ^(math.MaxUint64 << (max + 1)) & (math.MaxUint64 << min) + } + + // Else, use a simple loop. + for i := min; i <= max; i += step { + bits |= 1 << i + } + return bits +} + +// all returns all bits within the given bounds. (plus the star bit) +func all(r bounds) uint64 { + return getBits(r.min, r.max, 1) | starBit +} + +// parseDescriptor returns a predefined schedule for the expression, or error if none matches. +func parseDescriptor(descriptor string) (Schedule, error) { + switch descriptor { + case "@yearly", "@annually": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: 1 << hours.min, + Dom: 1 << dom.min, + Month: 1 << months.min, + Dow: all(dow), + }, nil + + case "@monthly": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: 1 << hours.min, + Dom: 1 << dom.min, + Month: all(months), + Dow: all(dow), + }, nil + + case "@weekly": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: 1 << hours.min, + Dom: all(dom), + Month: all(months), + Dow: 1 << dow.min, + }, nil + + case "@daily", "@midnight": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: 1 << hours.min, + Dom: all(dom), + Month: all(months), + Dow: all(dow), + }, nil + + case "@hourly": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: all(hours), + Dom: all(dom), + Month: all(months), + Dow: all(dow), + }, nil + } + + const every = "@every " + if strings.HasPrefix(descriptor, every) { + duration, err := time.ParseDuration(descriptor[len(every):]) + if err != nil { + return nil, fmt.Errorf("Failed to parse duration %s: %s", descriptor, err) + } + return Every(duration), nil + } + + return nil, fmt.Errorf("Unrecognized descriptor: %s", descriptor) +} diff --git a/vendor/github.com/robfig/cron/spec.go b/vendor/github.com/robfig/cron/spec.go new file mode 100644 index 0000000000..aac9a60b95 --- /dev/null +++ b/vendor/github.com/robfig/cron/spec.go @@ -0,0 +1,158 @@ +package cron + +import "time" + +// SpecSchedule specifies a duty cycle (to the second granularity), based on a +// traditional crontab specification. It is computed initially and stored as bit sets. +type SpecSchedule struct { + Second, Minute, Hour, Dom, Month, Dow uint64 +} + +// bounds provides a range of acceptable values (plus a map of name to value). +type bounds struct { + min, max uint + names map[string]uint +} + +// The bounds for each field. +var ( + seconds = bounds{0, 59, nil} + minutes = bounds{0, 59, nil} + hours = bounds{0, 23, nil} + dom = bounds{1, 31, nil} + months = bounds{1, 12, map[string]uint{ + "jan": 1, + "feb": 2, + "mar": 3, + "apr": 4, + "may": 5, + "jun": 6, + "jul": 7, + "aug": 8, + "sep": 9, + "oct": 10, + "nov": 11, + "dec": 12, + }} + dow = bounds{0, 6, map[string]uint{ + "sun": 0, + "mon": 1, + "tue": 2, + "wed": 3, + "thu": 4, + "fri": 5, + "sat": 6, + }} +) + +const ( + // Set the top bit if a star was included in the expression. + starBit = 1 << 63 +) + +// Next returns the next time this schedule is activated, greater than the given +// time. If no time can be found to satisfy the schedule, return the zero time. +func (s *SpecSchedule) Next(t time.Time) time.Time { + // General approach: + // For Month, Day, Hour, Minute, Second: + // Check if the time value matches. If yes, continue to the next field. + // If the field doesn't match the schedule, then increment the field until it matches. + // While incrementing the field, a wrap-around brings it back to the beginning + // of the field list (since it is necessary to re-verify previous field + // values) + + // Start at the earliest possible time (the upcoming second). + t = t.Add(1*time.Second - time.Duration(t.Nanosecond())*time.Nanosecond) + + // This flag indicates whether a field has been incremented. + added := false + + // If no time is found within five years, return zero. + yearLimit := t.Year() + 5 + +WRAP: + if t.Year() > yearLimit { + return time.Time{} + } + + // Find the first applicable month. + // If it's this month, then do nothing. + for 1< 0 + dowMatch bool = 1< 0 + ) + if s.Dom&starBit > 0 || s.Dow&starBit > 0 { + return domMatch && dowMatch + } + return domMatch || dowMatch +} diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go new file mode 100644 index 0000000000..9857fe53d3 --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -0,0 +1,66 @@ +// Copyright 2016 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 errgroup provides synchronization, error propagation, and Context +// cancelation for groups of goroutines working on subtasks of a common task. +package errgroup + +import ( + "context" + "sync" +) + +// A Group is a collection of goroutines working on subtasks that are part of +// the same overall task. +// +// A zero Group is valid and does not cancel on error. +type Group struct { + cancel func() + + wg sync.WaitGroup + + errOnce sync.Once + err error +} + +// WithContext returns a new Group and an associated Context derived from ctx. +// +// The derived Context is canceled the first time a function passed to Go +// returns a non-nil error or the first time Wait returns, whichever occurs +// first. +func WithContext(ctx context.Context) (*Group, context.Context) { + ctx, cancel := context.WithCancel(ctx) + return &Group{cancel: cancel}, ctx +} + +// Wait blocks until all function calls from the Go method have returned, then +// returns the first non-nil error (if any) from them. +func (g *Group) Wait() error { + g.wg.Wait() + if g.cancel != nil { + g.cancel() + } + return g.err +} + +// Go calls the given function in a new goroutine. +// +// The first call to return a non-nil error cancels the group; its error will be +// returned by Wait. +func (g *Group) Go(f func() error) { + g.wg.Add(1) + + go func() { + defer g.wg.Done() + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel() + } + }) + } + }() +} diff --git a/vendor/k8s.io/api/admission/v1beta1/doc.go b/vendor/k8s.io/api/admission/v1beta1/doc.go new file mode 100644 index 0000000000..92f7c19d26 --- /dev/null +++ b/vendor/k8s.io/api/admission/v1beta1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package +// +k8s:openapi-gen=false + +// +groupName=admission.k8s.io + +package v1beta1 // import "k8s.io/api/admission/v1beta1" diff --git a/vendor/k8s.io/api/admission/v1beta1/generated.pb.go b/vendor/k8s.io/api/admission/v1beta1/generated.pb.go new file mode 100644 index 0000000000..3bf0d1c622 --- /dev/null +++ b/vendor/k8s.io/api/admission/v1beta1/generated.pb.go @@ -0,0 +1,1573 @@ +/* +Copyright 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. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/admission/v1beta1/generated.proto + +/* + Package v1beta1 is a generated protocol buffer package. + + It is generated from these files: + k8s.io/kubernetes/vendor/k8s.io/api/admission/v1beta1/generated.proto + + It has these top-level messages: + AdmissionRequest + AdmissionResponse + AdmissionReview +*/ +package v1beta1 + +import ( + fmt "fmt" + + proto "github.com/gogo/protobuf/proto" + + math "math" + + k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + k8s_io_apimachinery_pkg_types "k8s.io/apimachinery/pkg/types" + + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + + strings "strings" + + reflect "reflect" + + io "io" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +func (m *AdmissionRequest) Reset() { *m = AdmissionRequest{} } +func (*AdmissionRequest) ProtoMessage() {} +func (*AdmissionRequest) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} } + +func (m *AdmissionResponse) Reset() { *m = AdmissionResponse{} } +func (*AdmissionResponse) ProtoMessage() {} +func (*AdmissionResponse) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} } + +func (m *AdmissionReview) Reset() { *m = AdmissionReview{} } +func (*AdmissionReview) ProtoMessage() {} +func (*AdmissionReview) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} } + +func init() { + proto.RegisterType((*AdmissionRequest)(nil), "k8s.io.api.admission.v1beta1.AdmissionRequest") + proto.RegisterType((*AdmissionResponse)(nil), "k8s.io.api.admission.v1beta1.AdmissionResponse") + proto.RegisterType((*AdmissionReview)(nil), "k8s.io.api.admission.v1beta1.AdmissionReview") +} +func (m *AdmissionRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AdmissionRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) + i += copy(dAtA[i:], m.UID) + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Kind.Size())) + n1, err := m.Kind.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Resource.Size())) + n2, err := m.Resource.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + dAtA[i] = 0x22 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.SubResource))) + i += copy(dAtA[i:], m.SubResource) + dAtA[i] = 0x2a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + dAtA[i] = 0x32 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i += copy(dAtA[i:], m.Namespace) + dAtA[i] = 0x3a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operation))) + i += copy(dAtA[i:], m.Operation) + dAtA[i] = 0x42 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.UserInfo.Size())) + n3, err := m.UserInfo.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + dAtA[i] = 0x4a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Object.Size())) + n4, err := m.Object.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + dAtA[i] = 0x52 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.OldObject.Size())) + n5, err := m.OldObject.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + if m.DryRun != nil { + dAtA[i] = 0x58 + i++ + if *m.DryRun { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + dAtA[i] = 0x62 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Options.Size())) + n6, err := m.Options.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n6 + if m.RequestKind != nil { + dAtA[i] = 0x6a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.RequestKind.Size())) + n7, err := m.RequestKind.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n7 + } + if m.RequestResource != nil { + dAtA[i] = 0x72 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.RequestResource.Size())) + n8, err := m.RequestResource.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n8 + } + dAtA[i] = 0x7a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.RequestSubResource))) + i += copy(dAtA[i:], m.RequestSubResource) + return i, nil +} + +func (m *AdmissionResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AdmissionResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) + i += copy(dAtA[i:], m.UID) + dAtA[i] = 0x10 + i++ + if m.Allowed { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + if m.Result != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Result.Size())) + n9, err := m.Result.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n9 + } + if m.Patch != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Patch))) + i += copy(dAtA[i:], m.Patch) + } + if m.PatchType != nil { + dAtA[i] = 0x2a + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.PatchType))) + i += copy(dAtA[i:], *m.PatchType) + } + if len(m.AuditAnnotations) > 0 { + keysForAuditAnnotations := make([]string, 0, len(m.AuditAnnotations)) + for k := range m.AuditAnnotations { + keysForAuditAnnotations = append(keysForAuditAnnotations, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAuditAnnotations) + for _, k := range keysForAuditAnnotations { + dAtA[i] = 0x32 + i++ + v := m.AuditAnnotations[string(k)] + mapSize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) + i = encodeVarintGenerated(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(len(v))) + i += copy(dAtA[i:], v) + } + } + return i, nil +} + +func (m *AdmissionReview) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AdmissionReview) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Request != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Request.Size())) + n10, err := m.Request.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n10 + } + if m.Response != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintGenerated(dAtA, i, uint64(m.Response.Size())) + n11, err := m.Response.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n11 + } + return i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *AdmissionRequest) Size() (n int) { + var l int + _ = l + l = len(m.UID) + n += 1 + l + sovGenerated(uint64(l)) + l = m.Kind.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Resource.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.SubResource) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Operation) + n += 1 + l + sovGenerated(uint64(l)) + l = m.UserInfo.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Object.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.OldObject.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.DryRun != nil { + n += 2 + } + l = m.Options.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.RequestKind != nil { + l = m.RequestKind.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.RequestResource != nil { + l = m.RequestResource.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.RequestSubResource) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *AdmissionResponse) Size() (n int) { + var l int + _ = l + l = len(m.UID) + n += 1 + l + sovGenerated(uint64(l)) + n += 2 + if m.Result != nil { + l = m.Result.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Patch != nil { + l = len(m.Patch) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.PatchType != nil { + l = len(*m.PatchType) + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.AuditAnnotations) > 0 { + for k, v := range m.AuditAnnotations { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } + return n +} + +func (m *AdmissionReview) Size() (n int) { + var l int + _ = l + if m.Request != nil { + l = m.Request.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Response != nil { + l = m.Response.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func sovGenerated(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *AdmissionRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&AdmissionRequest{`, + `UID:` + fmt.Sprintf("%v", this.UID) + `,`, + `Kind:` + strings.Replace(strings.Replace(this.Kind.String(), "GroupVersionKind", "k8s_io_apimachinery_pkg_apis_meta_v1.GroupVersionKind", 1), `&`, ``, 1) + `,`, + `Resource:` + strings.Replace(strings.Replace(this.Resource.String(), "GroupVersionResource", "k8s_io_apimachinery_pkg_apis_meta_v1.GroupVersionResource", 1), `&`, ``, 1) + `,`, + `SubResource:` + fmt.Sprintf("%v", this.SubResource) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `Operation:` + fmt.Sprintf("%v", this.Operation) + `,`, + `UserInfo:` + strings.Replace(strings.Replace(this.UserInfo.String(), "UserInfo", "k8s_io_api_authentication_v1.UserInfo", 1), `&`, ``, 1) + `,`, + `Object:` + strings.Replace(strings.Replace(this.Object.String(), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `OldObject:` + strings.Replace(strings.Replace(this.OldObject.String(), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `DryRun:` + valueToStringGenerated(this.DryRun) + `,`, + `Options:` + strings.Replace(strings.Replace(this.Options.String(), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `RequestKind:` + strings.Replace(fmt.Sprintf("%v", this.RequestKind), "GroupVersionKind", "k8s_io_apimachinery_pkg_apis_meta_v1.GroupVersionKind", 1) + `,`, + `RequestResource:` + strings.Replace(fmt.Sprintf("%v", this.RequestResource), "GroupVersionResource", "k8s_io_apimachinery_pkg_apis_meta_v1.GroupVersionResource", 1) + `,`, + `RequestSubResource:` + fmt.Sprintf("%v", this.RequestSubResource) + `,`, + `}`, + }, "") + return s +} +func (this *AdmissionResponse) String() string { + if this == nil { + return "nil" + } + keysForAuditAnnotations := make([]string, 0, len(this.AuditAnnotations)) + for k := range this.AuditAnnotations { + keysForAuditAnnotations = append(keysForAuditAnnotations, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAuditAnnotations) + mapStringForAuditAnnotations := "map[string]string{" + for _, k := range keysForAuditAnnotations { + mapStringForAuditAnnotations += fmt.Sprintf("%v: %v,", k, this.AuditAnnotations[k]) + } + mapStringForAuditAnnotations += "}" + s := strings.Join([]string{`&AdmissionResponse{`, + `UID:` + fmt.Sprintf("%v", this.UID) + `,`, + `Allowed:` + fmt.Sprintf("%v", this.Allowed) + `,`, + `Result:` + strings.Replace(fmt.Sprintf("%v", this.Result), "Status", "k8s_io_apimachinery_pkg_apis_meta_v1.Status", 1) + `,`, + `Patch:` + valueToStringGenerated(this.Patch) + `,`, + `PatchType:` + valueToStringGenerated(this.PatchType) + `,`, + `AuditAnnotations:` + mapStringForAuditAnnotations + `,`, + `}`, + }, "") + return s +} +func (this *AdmissionReview) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&AdmissionReview{`, + `Request:` + strings.Replace(fmt.Sprintf("%v", this.Request), "AdmissionRequest", "AdmissionRequest", 1) + `,`, + `Response:` + strings.Replace(fmt.Sprintf("%v", this.Response), "AdmissionResponse", "AdmissionResponse", 1) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *AdmissionRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AdmissionRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AdmissionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UID = k8s_io_apimachinery_pkg_types.UID(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Kind.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubResource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubResource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Operation", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Operation = Operation(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Object", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Object.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OldObject", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.OldObject.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DryRun", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.DryRun = &b + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Options.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestKind", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RequestKind == nil { + m.RequestKind = &k8s_io_apimachinery_pkg_apis_meta_v1.GroupVersionKind{} + } + if err := m.RequestKind.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestResource", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RequestResource == nil { + m.RequestResource = &k8s_io_apimachinery_pkg_apis_meta_v1.GroupVersionResource{} + } + if err := m.RequestResource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestSubResource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RequestSubResource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AdmissionResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AdmissionResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AdmissionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UID = k8s_io_apimachinery_pkg_types.UID(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowed", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Allowed = bool(v != 0) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Result == nil { + m.Result = &k8s_io_apimachinery_pkg_apis_meta_v1.Status{} + } + if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Patch", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Patch = append(m.Patch[:0], dAtA[iNdEx:postIndex]...) + if m.Patch == nil { + m.Patch = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PatchType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := PatchType(dAtA[iNdEx:postIndex]) + m.PatchType = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuditAnnotations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuditAnnotations == nil { + m.AuditAnnotations = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.AuditAnnotations[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AdmissionReview) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AdmissionReview: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AdmissionReview: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Request == nil { + m.Request = &AdmissionRequest{} + } + if err := m.Request.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Response", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Response == nil { + m.Response = &AdmissionResponse{} + } + if err := m.Response.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipGenerated(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") +) + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/admission/v1beta1/generated.proto", fileDescriptorGenerated) +} + +var fileDescriptorGenerated = []byte{ + // 905 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4d, 0x6f, 0x23, 0x35, + 0x18, 0xce, 0x6c, 0xd2, 0x24, 0xe3, 0x94, 0x4d, 0xd6, 0x0b, 0xd2, 0x28, 0x42, 0x93, 0xd0, 0x03, + 0x2a, 0xd2, 0xd6, 0x43, 0x2b, 0x58, 0x55, 0x2b, 0x2e, 0x1d, 0x5a, 0xa1, 0x82, 0xb4, 0xad, 0xbc, + 0x1b, 0xb4, 0x70, 0x40, 0x72, 0x32, 0xde, 0x64, 0x48, 0x62, 0x0f, 0x63, 0x4f, 0x4a, 0x6e, 0x88, + 0x2b, 0x17, 0xfe, 0x01, 0x3f, 0x86, 0x4b, 0x8f, 0x7b, 0xdc, 0x53, 0x44, 0xc3, 0xbf, 0xe8, 0x09, + 0xd9, 0xe3, 0xc9, 0xcc, 0x26, 0x2d, 0xec, 0x07, 0xa7, 0x99, 0xf7, 0xe3, 0x79, 0x5e, 0xfb, 0x79, + 0x5f, 0xdb, 0xe0, 0x64, 0x7c, 0x28, 0x50, 0xc8, 0xbd, 0x71, 0xd2, 0xa7, 0x31, 0xa3, 0x92, 0x0a, + 0x6f, 0x46, 0x59, 0xc0, 0x63, 0xcf, 0x04, 0x48, 0x14, 0x7a, 0x24, 0x98, 0x86, 0x42, 0x84, 0x9c, + 0x79, 0xb3, 0xfd, 0x3e, 0x95, 0x64, 0xdf, 0x1b, 0x52, 0x46, 0x63, 0x22, 0x69, 0x80, 0xa2, 0x98, + 0x4b, 0x0e, 0x3f, 0x4c, 0xb3, 0x11, 0x89, 0x42, 0xb4, 0xca, 0x46, 0x26, 0xbb, 0xbd, 0x37, 0x0c, + 0xe5, 0x28, 0xe9, 0xa3, 0x01, 0x9f, 0x7a, 0x43, 0x3e, 0xe4, 0x9e, 0x06, 0xf5, 0x93, 0xe7, 0xda, + 0xd2, 0x86, 0xfe, 0x4b, 0xc9, 0xda, 0x0f, 0x8a, 0xa5, 0x13, 0x39, 0xa2, 0x4c, 0x86, 0x03, 0x22, + 0xd3, 0xfa, 0xeb, 0xa5, 0xdb, 0x9f, 0xe5, 0xd9, 0x53, 0x32, 0x18, 0x85, 0x8c, 0xc6, 0x73, 0x2f, + 0x1a, 0x0f, 0x95, 0x43, 0x78, 0x53, 0x2a, 0xc9, 0x4d, 0x28, 0xef, 0x36, 0x54, 0x9c, 0x30, 0x19, + 0x4e, 0xe9, 0x06, 0xe0, 0xe1, 0x7f, 0x01, 0xc4, 0x60, 0x44, 0xa7, 0x64, 0x1d, 0xb7, 0xf3, 0x87, + 0x0d, 0x5a, 0x47, 0x99, 0x22, 0x98, 0xfe, 0x94, 0x50, 0x21, 0xa1, 0x0f, 0xca, 0x49, 0x18, 0x38, + 0x56, 0xd7, 0xda, 0xb5, 0xfd, 0x4f, 0x2f, 0x17, 0x9d, 0xd2, 0x72, 0xd1, 0x29, 0xf7, 0x4e, 0x8f, + 0xaf, 0x17, 0x9d, 0x8f, 0x6e, 0x2b, 0x24, 0xe7, 0x11, 0x15, 0xa8, 0x77, 0x7a, 0x8c, 0x15, 0x18, + 0x3e, 0x03, 0x95, 0x71, 0xc8, 0x02, 0xe7, 0x4e, 0xd7, 0xda, 0x6d, 0x1c, 0x3c, 0x44, 0x79, 0x07, + 0x56, 0x30, 0x14, 0x8d, 0x87, 0xca, 0x21, 0x90, 0x92, 0x01, 0xcd, 0xf6, 0xd1, 0x57, 0x31, 0x4f, + 0xa2, 0x6f, 0x69, 0xac, 0x16, 0xf3, 0x4d, 0xc8, 0x02, 0x7f, 0xdb, 0x14, 0xaf, 0x28, 0x0b, 0x6b, + 0x46, 0x38, 0x02, 0xf5, 0x98, 0x0a, 0x9e, 0xc4, 0x03, 0xea, 0x94, 0x35, 0xfb, 0xa3, 0x37, 0x67, + 0xc7, 0x86, 0xc1, 0x6f, 0x99, 0x0a, 0xf5, 0xcc, 0x83, 0x57, 0xec, 0xf0, 0x73, 0xd0, 0x10, 0x49, + 0x3f, 0x0b, 0x38, 0x15, 0xad, 0xc7, 0x7d, 0x03, 0x68, 0x3c, 0xc9, 0x43, 0xb8, 0x98, 0x07, 0xbb, + 0xa0, 0xc2, 0xc8, 0x94, 0x3a, 0x5b, 0x3a, 0x7f, 0xb5, 0x85, 0xc7, 0x64, 0x4a, 0xb1, 0x8e, 0x40, + 0x0f, 0xd8, 0xea, 0x2b, 0x22, 0x32, 0xa0, 0x4e, 0x55, 0xa7, 0xdd, 0x33, 0x69, 0xf6, 0xe3, 0x2c, + 0x80, 0xf3, 0x1c, 0xf8, 0x05, 0xb0, 0x79, 0xa4, 0x1a, 0x17, 0x72, 0xe6, 0xd4, 0x34, 0xc0, 0xcd, + 0x00, 0x67, 0x59, 0xe0, 0xba, 0x68, 0xe0, 0x1c, 0x00, 0x9f, 0x82, 0x7a, 0x22, 0x68, 0x7c, 0xca, + 0x9e, 0x73, 0xa7, 0xae, 0x15, 0xfb, 0x18, 0x15, 0x4f, 0xc4, 0x2b, 0x43, 0xac, 0x94, 0xea, 0x99, + 0xec, 0x5c, 0x9d, 0xcc, 0x83, 0x57, 0x4c, 0xb0, 0x07, 0xaa, 0xbc, 0xff, 0x23, 0x1d, 0x48, 0xc7, + 0xd6, 0x9c, 0x7b, 0xb7, 0x76, 0xc1, 0xcc, 0x20, 0xc2, 0xe4, 0xe2, 0xe4, 0x67, 0x49, 0x99, 0x6a, + 0x80, 0x7f, 0xd7, 0x50, 0x57, 0xcf, 0x34, 0x09, 0x36, 0x64, 0xf0, 0x07, 0x60, 0xf3, 0x49, 0x90, + 0x3a, 0x1d, 0xf0, 0x36, 0xcc, 0x2b, 0x29, 0xcf, 0x32, 0x1e, 0x9c, 0x53, 0xc2, 0x1d, 0x50, 0x0d, + 0xe2, 0x39, 0x4e, 0x98, 0xd3, 0xe8, 0x5a, 0xbb, 0x75, 0x1f, 0xa8, 0x35, 0x1c, 0x6b, 0x0f, 0x36, + 0x11, 0xf8, 0x0c, 0xd4, 0x78, 0xa4, 0xc4, 0x10, 0xce, 0xf6, 0xdb, 0xac, 0xa0, 0x69, 0x56, 0x50, + 0x3b, 0x4b, 0x59, 0x70, 0x46, 0x07, 0x43, 0xd0, 0x88, 0xd3, 0x53, 0xa6, 0x26, 0xda, 0x79, 0xef, + 0x9d, 0x4e, 0x47, 0x53, 0x8d, 0x21, 0xce, 0xe9, 0x70, 0x91, 0x1b, 0xce, 0x41, 0xd3, 0x98, 0xab, + 0x09, 0xbe, 0xfb, 0xce, 0xc7, 0xe5, 0xfe, 0x72, 0xd1, 0x69, 0xe2, 0x57, 0x69, 0xf1, 0x7a, 0x1d, + 0xf8, 0x35, 0x80, 0xc6, 0x55, 0x38, 0x24, 0x4e, 0x53, 0xcf, 0x6d, 0xdb, 0x68, 0x03, 0xf1, 0x46, + 0x06, 0xbe, 0x01, 0xb5, 0xf3, 0x6b, 0x05, 0xdc, 0x2b, 0xdc, 0x50, 0x22, 0xe2, 0x4c, 0xd0, 0xff, + 0xe5, 0x8a, 0xfa, 0x04, 0xd4, 0xc8, 0x64, 0xc2, 0x2f, 0x68, 0x7a, 0x4b, 0xd5, 0xf3, 0xb6, 0x1d, + 0xa5, 0x6e, 0x9c, 0xc5, 0xe1, 0x39, 0xa8, 0x0a, 0x49, 0x64, 0x22, 0xcc, 0x8d, 0xf3, 0xe0, 0xf5, + 0x24, 0x7c, 0xa2, 0x31, 0xe9, 0x88, 0x61, 0x2a, 0x92, 0x89, 0xc4, 0x86, 0x07, 0x76, 0xc0, 0x56, + 0x44, 0xe4, 0x60, 0xa4, 0x6f, 0x95, 0x6d, 0xdf, 0x5e, 0x2e, 0x3a, 0x5b, 0xe7, 0xca, 0x81, 0x53, + 0x3f, 0x3c, 0x04, 0xb6, 0xfe, 0x79, 0x3a, 0x8f, 0xb2, 0xab, 0xa4, 0xad, 0x86, 0xfa, 0x3c, 0x73, + 0x5e, 0x17, 0x0d, 0x9c, 0x27, 0xc3, 0xdf, 0x2c, 0xd0, 0x22, 0x49, 0x10, 0xca, 0x23, 0xc6, 0xb8, + 0x24, 0xe9, 0x1c, 0x57, 0xbb, 0xe5, 0xdd, 0xc6, 0xc1, 0x09, 0xfa, 0xb7, 0x97, 0x10, 0x6d, 0xe8, + 0x8c, 0x8e, 0xd6, 0x78, 0x4e, 0x98, 0x8c, 0xe7, 0xbe, 0x63, 0x84, 0x6a, 0xad, 0x87, 0xf1, 0x46, + 0xe1, 0xf6, 0x97, 0xe0, 0x83, 0x1b, 0x49, 0x60, 0x0b, 0x94, 0xc7, 0x74, 0x9e, 0xb6, 0x10, 0xab, + 0x5f, 0xf8, 0x3e, 0xd8, 0x9a, 0x91, 0x49, 0x42, 0x75, 0x3b, 0x6c, 0x9c, 0x1a, 0x8f, 0xee, 0x1c, + 0x5a, 0x3b, 0x7f, 0x5a, 0xa0, 0x59, 0x58, 0xdc, 0x2c, 0xa4, 0x17, 0xb0, 0x07, 0x6a, 0x66, 0x5c, + 0x34, 0x47, 0xe3, 0x00, 0xbd, 0xf6, 0xe6, 0x34, 0xca, 0x6f, 0xa8, 0x56, 0x67, 0xb3, 0x9c, 0x71, + 0xc1, 0xef, 0xf4, 0xf3, 0xa2, 0x77, 0x6f, 0x1e, 0x2f, 0xef, 0x0d, 0x45, 0xf3, 0xb7, 0xcd, 0x7b, + 0xa2, 0x2d, 0xbc, 0xa2, 0xf3, 0xf7, 0x2e, 0xaf, 0xdc, 0xd2, 0x8b, 0x2b, 0xb7, 0xf4, 0xf2, 0xca, + 0x2d, 0xfd, 0xb2, 0x74, 0xad, 0xcb, 0xa5, 0x6b, 0xbd, 0x58, 0xba, 0xd6, 0xcb, 0xa5, 0x6b, 0xfd, + 0xb5, 0x74, 0xad, 0xdf, 0xff, 0x76, 0x4b, 0xdf, 0xd7, 0x0c, 0xf1, 0x3f, 0x01, 0x00, 0x00, 0xff, + 0xff, 0xda, 0xe1, 0x0b, 0x41, 0xfd, 0x08, 0x00, 0x00, +} diff --git a/vendor/k8s.io/api/admission/v1beta1/generated.proto b/vendor/k8s.io/api/admission/v1beta1/generated.proto new file mode 100644 index 0000000000..59f92a70d2 --- /dev/null +++ b/vendor/k8s.io/api/admission/v1beta1/generated.proto @@ -0,0 +1,160 @@ +/* +Copyright 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. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = 'proto2'; + +package k8s.io.api.admission.v1beta1; + +import "k8s.io/api/authentication/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "v1beta1"; + +// AdmissionRequest describes the admission.Attributes for the admission request. +message AdmissionRequest { + // UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are + // otherwise identical (parallel requests, requests when earlier requests did not modify etc) + // The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. + // It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + optional string uid = 1; + + // Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) + optional k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind kind = 2; + + // Resource is the fully-qualified resource being requested (for example, v1.pods) + optional k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionResource resource = 3; + + // SubResource is the subresource being requested, if any (for example, "status" or "scale") + // +optional + optional string subResource = 4; + + // RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale). + // If this is specified and differs from the value in "kind", an equivalent match and conversion was performed. + // + // For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of + // `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`, + // an API request to apps/v1beta1 deployments would be converted and sent to the webhook + // with `kind: {group:"apps", version:"v1", kind:"Deployment"}` (matching the rule the webhook registered for), + // and `requestKind: {group:"apps", version:"v1beta1", kind:"Deployment"}` (indicating the kind of the original API request). + // + // See documentation for the "matchPolicy" field in the webhook configuration type for more details. + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind requestKind = 13; + + // RequestResource is the fully-qualified resource of the original API request (for example, v1.pods). + // If this is specified and differs from the value in "resource", an equivalent match and conversion was performed. + // + // For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of + // `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`, + // an API request to apps/v1beta1 deployments would be converted and sent to the webhook + // with `resource: {group:"apps", version:"v1", resource:"deployments"}` (matching the resource the webhook registered for), + // and `requestResource: {group:"apps", version:"v1beta1", resource:"deployments"}` (indicating the resource of the original API request). + // + // See documentation for the "matchPolicy" field in the webhook configuration type. + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionResource requestResource = 14; + + // RequestSubResource is the name of the subresource of the original API request, if any (for example, "status" or "scale") + // If this is specified and differs from the value in "subResource", an equivalent match and conversion was performed. + // See documentation for the "matchPolicy" field in the webhook configuration type. + // +optional + optional string requestSubResource = 15; + + // Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and + // rely on the server to generate the name. If that is the case, this method will return the empty string. + // +optional + optional string name = 5; + + // Namespace is the namespace associated with the request (if any). + // +optional + optional string namespace = 6; + + // Operation is the operation being performed. This may be different than the operation + // requested. e.g. a patch can result in either a CREATE or UPDATE Operation. + optional string operation = 7; + + // UserInfo is information about the requesting user + optional k8s.io.api.authentication.v1.UserInfo userInfo = 8; + + // Object is the object from the incoming request prior to default values being applied + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension object = 9; + + // OldObject is the existing object. Only populated for UPDATE requests. + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension oldObject = 10; + + // DryRun indicates that modifications will definitely not be persisted for this request. + // Defaults to false. + // +optional + optional bool dryRun = 11; + + // Options is the operation option structure of the operation being performed. + // e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be + // different than the options the caller provided. e.g. for a patch request the performed + // Operation might be a CREATE, in which case the Options will a + // `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`. + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension options = 12; +} + +// AdmissionResponse describes an admission response. +message AdmissionResponse { + // UID is an identifier for the individual request/response. + // This should be copied over from the corresponding AdmissionRequest. + optional string uid = 1; + + // Allowed indicates whether or not the admission request was permitted. + optional bool allowed = 2; + + // Result contains extra details into why an admission request was denied. + // This field IS NOT consulted in any way if "Allowed" is "true". + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.Status status = 3; + + // The patch body. Currently we only support "JSONPatch" which implements RFC 6902. + // +optional + optional bytes patch = 4; + + // The type of Patch. Currently we only allow "JSONPatch". + // +optional + optional string patchType = 5; + + // AuditAnnotations is an unstructured key value map set by remote admission controller (e.g. error=image-blacklisted). + // MutatingAdmissionWebhook and ValidatingAdmissionWebhook admission controller will prefix the keys with + // admission webhook name (e.g. imagepolicy.example.com/error=image-blacklisted). AuditAnnotations will be provided by + // the admission webhook to add additional context to the audit log for this request. + // +optional + map auditAnnotations = 6; +} + +// AdmissionReview describes an admission review request/response. +message AdmissionReview { + // Request describes the attributes for the admission request. + // +optional + optional AdmissionRequest request = 1; + + // Response describes the attributes for the admission response. + // +optional + optional AdmissionResponse response = 2; +} + diff --git a/vendor/k8s.io/api/admission/v1beta1/register.go b/vendor/k8s.io/api/admission/v1beta1/register.go new file mode 100644 index 0000000000..78d21a0c8a --- /dev/null +++ b/vendor/k8s.io/api/admission/v1beta1/register.go @@ -0,0 +1,51 @@ +/* +Copyright 2017 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 v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name for this API. +const GroupName = "admission.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. + // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &AdmissionReview{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/admission/v1beta1/types.go b/vendor/k8s.io/api/admission/v1beta1/types.go new file mode 100644 index 0000000000..e968720e71 --- /dev/null +++ b/vendor/k8s.io/api/admission/v1beta1/types.go @@ -0,0 +1,162 @@ +/* +Copyright 2017 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 v1beta1 + +import ( + authenticationv1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AdmissionReview describes an admission review request/response. +type AdmissionReview struct { + metav1.TypeMeta `json:",inline"` + // Request describes the attributes for the admission request. + // +optional + Request *AdmissionRequest `json:"request,omitempty" protobuf:"bytes,1,opt,name=request"` + // Response describes the attributes for the admission response. + // +optional + Response *AdmissionResponse `json:"response,omitempty" protobuf:"bytes,2,opt,name=response"` +} + +// AdmissionRequest describes the admission.Attributes for the admission request. +type AdmissionRequest struct { + // UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are + // otherwise identical (parallel requests, requests when earlier requests did not modify etc) + // The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. + // It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"` + // Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) + Kind metav1.GroupVersionKind `json:"kind" protobuf:"bytes,2,opt,name=kind"` + // Resource is the fully-qualified resource being requested (for example, v1.pods) + Resource metav1.GroupVersionResource `json:"resource" protobuf:"bytes,3,opt,name=resource"` + // SubResource is the subresource being requested, if any (for example, "status" or "scale") + // +optional + SubResource string `json:"subResource,omitempty" protobuf:"bytes,4,opt,name=subResource"` + + // RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale). + // If this is specified and differs from the value in "kind", an equivalent match and conversion was performed. + // + // For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of + // `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`, + // an API request to apps/v1beta1 deployments would be converted and sent to the webhook + // with `kind: {group:"apps", version:"v1", kind:"Deployment"}` (matching the rule the webhook registered for), + // and `requestKind: {group:"apps", version:"v1beta1", kind:"Deployment"}` (indicating the kind of the original API request). + // + // See documentation for the "matchPolicy" field in the webhook configuration type for more details. + // +optional + RequestKind *metav1.GroupVersionKind `json:"requestKind,omitempty" protobuf:"bytes,13,opt,name=requestKind"` + // RequestResource is the fully-qualified resource of the original API request (for example, v1.pods). + // If this is specified and differs from the value in "resource", an equivalent match and conversion was performed. + // + // For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of + // `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`, + // an API request to apps/v1beta1 deployments would be converted and sent to the webhook + // with `resource: {group:"apps", version:"v1", resource:"deployments"}` (matching the resource the webhook registered for), + // and `requestResource: {group:"apps", version:"v1beta1", resource:"deployments"}` (indicating the resource of the original API request). + // + // See documentation for the "matchPolicy" field in the webhook configuration type. + // +optional + RequestResource *metav1.GroupVersionResource `json:"requestResource,omitempty" protobuf:"bytes,14,opt,name=requestResource"` + // RequestSubResource is the name of the subresource of the original API request, if any (for example, "status" or "scale") + // If this is specified and differs from the value in "subResource", an equivalent match and conversion was performed. + // See documentation for the "matchPolicy" field in the webhook configuration type. + // +optional + RequestSubResource string `json:"requestSubResource,omitempty" protobuf:"bytes,15,opt,name=requestSubResource"` + + // Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and + // rely on the server to generate the name. If that is the case, this method will return the empty string. + // +optional + Name string `json:"name,omitempty" protobuf:"bytes,5,opt,name=name"` + // Namespace is the namespace associated with the request (if any). + // +optional + Namespace string `json:"namespace,omitempty" protobuf:"bytes,6,opt,name=namespace"` + // Operation is the operation being performed. This may be different than the operation + // requested. e.g. a patch can result in either a CREATE or UPDATE Operation. + Operation Operation `json:"operation" protobuf:"bytes,7,opt,name=operation"` + // UserInfo is information about the requesting user + UserInfo authenticationv1.UserInfo `json:"userInfo" protobuf:"bytes,8,opt,name=userInfo"` + // Object is the object from the incoming request prior to default values being applied + // +optional + Object runtime.RawExtension `json:"object,omitempty" protobuf:"bytes,9,opt,name=object"` + // OldObject is the existing object. Only populated for UPDATE requests. + // +optional + OldObject runtime.RawExtension `json:"oldObject,omitempty" protobuf:"bytes,10,opt,name=oldObject"` + // DryRun indicates that modifications will definitely not be persisted for this request. + // Defaults to false. + // +optional + DryRun *bool `json:"dryRun,omitempty" protobuf:"varint,11,opt,name=dryRun"` + // Options is the operation option structure of the operation being performed. + // e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be + // different than the options the caller provided. e.g. for a patch request the performed + // Operation might be a CREATE, in which case the Options will a + // `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`. + // +optional + Options runtime.RawExtension `json:"options,omitempty" protobuf:"bytes,12,opt,name=options"` +} + +// AdmissionResponse describes an admission response. +type AdmissionResponse struct { + // UID is an identifier for the individual request/response. + // This should be copied over from the corresponding AdmissionRequest. + UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"` + + // Allowed indicates whether or not the admission request was permitted. + Allowed bool `json:"allowed" protobuf:"varint,2,opt,name=allowed"` + + // Result contains extra details into why an admission request was denied. + // This field IS NOT consulted in any way if "Allowed" is "true". + // +optional + Result *metav1.Status `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` + + // The patch body. Currently we only support "JSONPatch" which implements RFC 6902. + // +optional + Patch []byte `json:"patch,omitempty" protobuf:"bytes,4,opt,name=patch"` + + // The type of Patch. Currently we only allow "JSONPatch". + // +optional + PatchType *PatchType `json:"patchType,omitempty" protobuf:"bytes,5,opt,name=patchType"` + + // AuditAnnotations is an unstructured key value map set by remote admission controller (e.g. error=image-blacklisted). + // MutatingAdmissionWebhook and ValidatingAdmissionWebhook admission controller will prefix the keys with + // admission webhook name (e.g. imagepolicy.example.com/error=image-blacklisted). AuditAnnotations will be provided by + // the admission webhook to add additional context to the audit log for this request. + // +optional + AuditAnnotations map[string]string `json:"auditAnnotations,omitempty" protobuf:"bytes,6,opt,name=auditAnnotations"` +} + +// PatchType is the type of patch being used to represent the mutated object +type PatchType string + +// PatchType constants. +const ( + PatchTypeJSONPatch PatchType = "JSONPatch" +) + +// Operation is the type of resource operation being checked for admission control +type Operation string + +// Operation constants +const ( + Create Operation = "CREATE" + Update Operation = "UPDATE" + Delete Operation = "DELETE" + Connect Operation = "CONNECT" +) diff --git a/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go new file mode 100644 index 0000000000..727080d0d4 --- /dev/null +++ b/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go @@ -0,0 +1,77 @@ +/* +Copyright 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 v1beta1 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-generated-swagger-docs.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_AdmissionRequest = map[string]string{ + "": "AdmissionRequest describes the admission.Attributes for the admission request.", + "uid": "UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are otherwise identical (parallel requests, requests when earlier requests did not modify etc) The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.", + "kind": "Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)", + "resource": "Resource is the fully-qualified resource being requested (for example, v1.pods)", + "subResource": "SubResource is the subresource being requested, if any (for example, \"status\" or \"scale\")", + "requestKind": "RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale). If this is specified and differs from the value in \"kind\", an equivalent match and conversion was performed.\n\nFor example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]` and `matchPolicy: Equivalent`, an API request to apps/v1beta1 deployments would be converted and sent to the webhook with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` (matching the rule the webhook registered for), and `requestKind: {group:\"apps\", version:\"v1beta1\", kind:\"Deployment\"}` (indicating the kind of the original API request).\n\nSee documentation for the \"matchPolicy\" field in the webhook configuration type for more details.", + "requestResource": "RequestResource is the fully-qualified resource of the original API request (for example, v1.pods). If this is specified and differs from the value in \"resource\", an equivalent match and conversion was performed.\n\nFor example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]` and `matchPolicy: Equivalent`, an API request to apps/v1beta1 deployments would be converted and sent to the webhook with `resource: {group:\"apps\", version:\"v1\", resource:\"deployments\"}` (matching the resource the webhook registered for), and `requestResource: {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` (indicating the resource of the original API request).\n\nSee documentation for the \"matchPolicy\" field in the webhook configuration type.", + "requestSubResource": "RequestSubResource is the name of the subresource of the original API request, if any (for example, \"status\" or \"scale\") If this is specified and differs from the value in \"subResource\", an equivalent match and conversion was performed. See documentation for the \"matchPolicy\" field in the webhook configuration type.", + "name": "Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and rely on the server to generate the name. If that is the case, this method will return the empty string.", + "namespace": "Namespace is the namespace associated with the request (if any).", + "operation": "Operation is the operation being performed. This may be different than the operation requested. e.g. a patch can result in either a CREATE or UPDATE Operation.", + "userInfo": "UserInfo is information about the requesting user", + "object": "Object is the object from the incoming request prior to default values being applied", + "oldObject": "OldObject is the existing object. Only populated for UPDATE requests.", + "dryRun": "DryRun indicates that modifications will definitely not be persisted for this request. Defaults to false.", + "options": "Options is the operation option structure of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be different than the options the caller provided. e.g. for a patch request the performed Operation might be a CREATE, in which case the Options will a `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.", +} + +func (AdmissionRequest) SwaggerDoc() map[string]string { + return map_AdmissionRequest +} + +var map_AdmissionResponse = map[string]string{ + "": "AdmissionResponse describes an admission response.", + "uid": "UID is an identifier for the individual request/response. This should be copied over from the corresponding AdmissionRequest.", + "allowed": "Allowed indicates whether or not the admission request was permitted.", + "status": "Result contains extra details into why an admission request was denied. This field IS NOT consulted in any way if \"Allowed\" is \"true\".", + "patch": "The patch body. Currently we only support \"JSONPatch\" which implements RFC 6902.", + "patchType": "The type of Patch. Currently we only allow \"JSONPatch\".", + "auditAnnotations": "AuditAnnotations is an unstructured key value map set by remote admission controller (e.g. error=image-blacklisted). MutatingAdmissionWebhook and ValidatingAdmissionWebhook admission controller will prefix the keys with admission webhook name (e.g. imagepolicy.example.com/error=image-blacklisted). AuditAnnotations will be provided by the admission webhook to add additional context to the audit log for this request.", +} + +func (AdmissionResponse) SwaggerDoc() map[string]string { + return map_AdmissionResponse +} + +var map_AdmissionReview = map[string]string{ + "": "AdmissionReview describes an admission review request/response.", + "request": "Request describes the attributes for the admission request.", + "response": "Response describes the attributes for the admission response.", +} + +func (AdmissionReview) SwaggerDoc() map[string]string { + return map_AdmissionReview +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/admission/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admission/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..e4704c86dd --- /dev/null +++ b/vendor/k8s.io/api/admission/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,136 @@ +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdmissionRequest) DeepCopyInto(out *AdmissionRequest) { + *out = *in + out.Kind = in.Kind + out.Resource = in.Resource + if in.RequestKind != nil { + in, out := &in.RequestKind, &out.RequestKind + *out = new(v1.GroupVersionKind) + **out = **in + } + if in.RequestResource != nil { + in, out := &in.RequestResource, &out.RequestResource + *out = new(v1.GroupVersionResource) + **out = **in + } + in.UserInfo.DeepCopyInto(&out.UserInfo) + in.Object.DeepCopyInto(&out.Object) + in.OldObject.DeepCopyInto(&out.OldObject) + if in.DryRun != nil { + in, out := &in.DryRun, &out.DryRun + *out = new(bool) + **out = **in + } + in.Options.DeepCopyInto(&out.Options) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmissionRequest. +func (in *AdmissionRequest) DeepCopy() *AdmissionRequest { + if in == nil { + return nil + } + out := new(AdmissionRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdmissionResponse) DeepCopyInto(out *AdmissionResponse) { + *out = *in + if in.Result != nil { + in, out := &in.Result, &out.Result + *out = new(v1.Status) + (*in).DeepCopyInto(*out) + } + if in.Patch != nil { + in, out := &in.Patch, &out.Patch + *out = make([]byte, len(*in)) + copy(*out, *in) + } + if in.PatchType != nil { + in, out := &in.PatchType, &out.PatchType + *out = new(PatchType) + **out = **in + } + if in.AuditAnnotations != nil { + in, out := &in.AuditAnnotations, &out.AuditAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmissionResponse. +func (in *AdmissionResponse) DeepCopy() *AdmissionResponse { + if in == nil { + return nil + } + out := new(AdmissionResponse) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdmissionReview) DeepCopyInto(out *AdmissionReview) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.Request != nil { + in, out := &in.Request, &out.Request + *out = new(AdmissionRequest) + (*in).DeepCopyInto(*out) + } + if in.Response != nil { + in, out := &in.Response, &out.Response + *out = new(AdmissionResponse) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmissionReview. +func (in *AdmissionReview) DeepCopy() *AdmissionReview { + if in == nil { + return nil + } + out := new(AdmissionReview) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AdmissionReview) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/knative.dev/eventing/AUTHORS b/vendor/knative.dev/eventing/AUTHORS new file mode 100644 index 0000000000..2ab352dbf3 --- /dev/null +++ b/vendor/knative.dev/eventing/AUTHORS @@ -0,0 +1,9 @@ +# This is the list of Knative authors for copyright purposes. +# +# This does not necessarily list everyone who has contributed code, since in +# some cases, their employer may be the copyright holder. To see the full list +# of contributors, see the revision history in source control. +Google LLC +Pivotal Software, Inc. +Red Hat, Inc. +IBM Corp diff --git a/vendor/knative.dev/eventing/LICENSE b/vendor/knative.dev/eventing/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/knative.dev/eventing/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/lifecycle_helper.go b/vendor/knative.dev/eventing/pkg/apis/duck/lifecycle_helper.go new file mode 100644 index 0000000000..c1b06b2de3 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/lifecycle_helper.go @@ -0,0 +1,33 @@ +/* +Copyright 2019 The Knative 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 duck + +import ( + appsv1 "k8s.io/api/apps/v1" +) + +// DeploymentIsAvailable determines if the provided deployment is available. Note that if it cannot +// determine the Deployment's availability, it returns `def` (short for default). +func DeploymentIsAvailable(d *appsv1.DeploymentStatus, def bool) bool { + // Check if the Deployment is available. + for _, cond := range d.Conditions { + if cond.Type == appsv1.DeploymentAvailable { + return cond.Status == "True" + } + } + return def +} diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channel_defaulter.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channel_defaulter.go new file mode 100644 index 0000000000..d11c262a40 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channel_defaulter.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +// TODO This should be placed in channel_defaults.go within messaging once Subscription is moved to messaging. +// Context: there is a cyclic dependency between eventing and messaging if we place this in messaging. Broker needs to +// depend on this, which is fine. But the problem arises due to messaging depending on eventing, mainly on +// Subscription-related objects for the Sequence type. We should first move Subscription down to messaging and then we +// can move this down. See https://github.com/knative/eventing/issues/1562. +// + +// ChannelDefaulter sets the default Channel CRD and Arguments on Channels that do not +// specify any implementation. +type ChannelDefaulter interface { + // GetDefault determines the default Channel CRD for the given namespace. + GetDefault(namespace string) *ChannelTemplateSpec +} + +var ( + // ChannelDefaulterSingleton is the global singleton used to default Channels that do not + // specify a Channel CRD. + ChannelDefaulterSingleton ChannelDefaulter +) diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channel_template_types.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channel_template_types.go new file mode 100644 index 0000000000..cb80d7d3d5 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channel_template_types.go @@ -0,0 +1,47 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type ChannelTemplateSpec struct { + metav1.TypeMeta `json:",inline"` + + // Spec defines the Spec to use for each channel created. Passed + // in verbatim to the Channel CRD as Spec section. + // +optional + Spec *runtime.RawExtension `json:"spec,omitempty"` +} + +// ChannelTemplateSpecInternal is an internal only version that includes ObjectMeta so that +// we can easily create new Channels off of it. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type ChannelTemplateSpecInternal struct { + metav1.TypeMeta `json:",inline"` + + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the Spec to use for each channel created. Passed + // in verbatim to the Channel CRD as Spec section. + // +optional + Spec *runtime.RawExtension `json:"spec,omitempty"` +} diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channelable_types.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channelable_types.go new file mode 100644 index 0000000000..778ec808d9 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/channelable_types.go @@ -0,0 +1,167 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "knative.dev/pkg/apis" + "knative.dev/pkg/apis/duck" + duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/pkg/apis/duck/v1alpha1" + duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Channelable is a skeleton type wrapping Subscribable and Addressable in the manner we expect resource writers +// defining compatible resources to embed it. We will typically use this type to deserialize +// Channelable ObjectReferences and access their subscription and address data. This is not a real resource. +type Channelable struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec is the part where the Channelable fulfills the Subscribable contract. + Spec ChannelableSpec `json:"spec,omitempty"` + + Status ChannelableStatus `json:"status,omitempty"` +} + +// ChannelableSpec contains Spec of the Channelable object +type ChannelableSpec struct { + SubscribableTypeSpec `json:",inline"` + + // DeliverySpec contains options controlling the event delivery + // +optional + Delivery *DeliverySpec `json:"delivery,omitempty"` +} + +// ChannelableStatus contains the Status of a Channelable object. +type ChannelableStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + // AddressStatus is the part where the Channelable fulfills the Addressable contract. + v1alpha1.AddressStatus `json:",inline"` + // Subscribers is populated with the statuses of each of the Channelable's subscribers. + SubscribableTypeStatus `json:",inline"` + // ErrorChannel is set by the channel when it supports native error handling via a channel + // +optional + ErrorChannel *corev1.ObjectReference `json:"errorChannel,omitempty"` +} + +var ( + // Verify Channelable resources meet duck contracts. + _ duck.Populatable = (*Channelable)(nil) + _ apis.Listable = (*Channelable)(nil) +) + +// Populate implements duck.Populatable +func (c *Channelable) Populate() { + c.Spec.Subscribable = &Subscribable{ + // Populate ALL fields + Subscribers: []SubscriberSpec{{ + UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1", + Generation: 1, + SubscriberURI: "call1", + ReplyURI: "sink2", + }, { + UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1", + Generation: 2, + SubscriberURI: "call2", + ReplyURI: "sink2", + }}, + } + retry := int32(5) + linear := BackoffPolicyLinear + delay := "5s" + c.Spec.Delivery = &DeliverySpec{ + DeadLetterSink: &apisv1alpha1.Destination{ + Ref: &corev1.ObjectReference{ + Name: "aname", + }, + URI: &apis.URL{ + Scheme: "http", + Host: "test-error-domain", + }, + }, + Retry: &retry, + BackoffPolicy: &linear, + BackoffDelay: &delay, + } + c.Status = ChannelableStatus{ + AddressStatus: v1alpha1.AddressStatus{ + Address: &v1alpha1.Addressable{ + // Populate ALL fields + Addressable: duckv1beta1.Addressable{ + URL: &apis.URL{ + Scheme: "http", + Host: "test-domain", + }, + }, + Hostname: "test-domain", + }, + }, + SubscribableTypeStatus: SubscribableTypeStatus{ + DeprecatedSubscribableStatus: &SubscribableStatus{ + Subscribers: []SubscriberStatus{{ + UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1", + ObservedGeneration: 1, + Ready: corev1.ConditionTrue, + Message: "Some message", + }, { + UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1", + ObservedGeneration: 2, + Ready: corev1.ConditionFalse, + Message: "Some message", + }}, + }, + SubscribableStatus: &SubscribableStatus{ + Subscribers: []SubscriberStatus{{ + UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1", + ObservedGeneration: 1, + Ready: corev1.ConditionTrue, + Message: "Some message", + }, { + UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1", + ObservedGeneration: 2, + Ready: corev1.ConditionFalse, + Message: "Some message", + }}, + }, + }, + } +} + +// GetListType implements apis.Listable +func (c *Channelable) GetListType() runtime.Object { + return &ChannelableList{} +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ChannelableList is a list of Channelable resources. +type ChannelableList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Channelable `json:"items"` +} diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/delivery_types.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/delivery_types.go new file mode 100644 index 0000000000..8a829be7ab --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/delivery_types.go @@ -0,0 +1,67 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" +) + +// DeliverySpec contains the delivery options for event senders, +// such as channelable and source. +type DeliverySpec struct { + // DeadLetterSink is the sink receiving event that couldn't be sent to + // a destination. + // +optional + DeadLetterSink *apisv1alpha1.Destination `json:"deadLetterSink,omitempty"` + + // Retry is the minimum number of retries the sender should attempt when + // sending an event before moving it to the dead letter sink. + // +optional + Retry *int32 `json:"retry,omitempty"` + + // BackoffPolicy is the retry backoff policy (linear, exponential) + // +optional + BackoffPolicy *BackoffPolicyType `json:"backoffPolicy,omitempty"` + + // BackoffDelay is the delay before retrying. + // More information on Duration format: https://www.ietf.org/rfc/rfc3339.txt + // + // For linear policy, backoff delay is the time interval between retries. + // For exponential policy , backoff delay is backoffDelay*2^ + // +optional + BackoffDelay *string +} + +// BackoffPolicyType is the type for backoff policies +type BackoffPolicyType string + +const ( + // Linear backoff policy + BackoffPolicyLinear BackoffPolicyType = "linear" + + // Exponential backoff policy + BackoffPolicyExponential BackoffPolicyType = "exponential" +) + +// DeliveryStatus contains the Status of an object supporting delivery options. +type DeliveryStatus struct { + // DeadLetterChannel is the reference to the native, platform specific channel + // where failed events are sent to. + // +optional + DeadLetterChannel *corev1.ObjectReference `json:"deadLetterChannel,omitempty"` +} diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/doc.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/doc.go new file mode 100644 index 0000000000..5019094b1e --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Api versions allow the api contract for a resource to be changed while keeping +// backward compatibility by support multiple concurrent versions +// of the same resource + +// Package v1alpha1 is the v1alpha1 version of the API. +// +k8s:deepcopy-gen=package +// +groupName=duck.knative.dev +package v1alpha1 diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/resource_types.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/resource_types.go new file mode 100644 index 0000000000..f49877b959 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/resource_types.go @@ -0,0 +1,51 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "knative.dev/pkg/apis" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Resource is a skeleton type wrapping all Kubernetes resources. It is typically used to watch +// arbitrary other resources (such as any Source or Addressable). This is not a real resource. +type Resource struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` +} + +// Ensure Resource satisfies apis.Listable +var _ apis.Listable = (*Resource)(nil) + +// GetListType implements apis.Listable. +func (*Resource) GetListType() runtime.Object { + return &ResourceList{} +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ResourceList is a list of KResource resources +type ResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Resource `json:"items"` +} diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/subscribable_types.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/subscribable_types.go new file mode 100644 index 0000000000..bed80fc395 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/subscribable_types.go @@ -0,0 +1,201 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "knative.dev/pkg/apis" + "knative.dev/pkg/apis/duck" +) + +// Subscribable is the schema for the subscribable portion of the spec +// section of the resource. +type Subscribable struct { + // This is the list of subscriptions for this subscribable. + // +patchMergeKey=uid + // +patchStrategy=merge + Subscribers []SubscriberSpec `json:"subscribers,omitempty" patchStrategy:"merge" patchMergeKey:"uid"` +} + +// Subscribable is an Implementable "duck type". +var _ duck.Implementable = (*Subscribable)(nil) + +// SubscriberSpec defines a single subscriber to a Subscribable. +// Ref is a reference to the Subscription this SubscriberSpec was created for +// SubscriberURI is the endpoint for the subscriber +// ReplyURI is the endpoint for the reply +// At least one of SubscriberURI and ReplyURI must be present +type SubscriberSpec struct { + // Deprecated: use UID. + // +optional + DeprecatedRef *corev1.ObjectReference `json:"ref,omitempty" yaml:"ref,omitempty"` + // UID is used to understand the origin of the subscriber. + // +optional + UID types.UID `json:"uid,omitempty"` + // Generation of the origin of the subscriber with uid:UID. + // +optional + Generation int64 `json:"generation,omitempty"` + // +optional + SubscriberURI string `json:"subscriberURI,omitempty"` + // +optional + ReplyURI string `json:"replyURI,omitempty"` +} + +// SubscribableStatus is the schema for the subscribable's status portion of the status +// section of the resource. +type SubscribableStatus struct { + // This is the list of subscription's statuses for this channel. + // +patchMergeKey=uid + // +patchStrategy=merge + Subscribers []SubscriberStatus `json:"subscribers,omitempty" patchStrategy:"merge" patchMergeKey:"uid"` +} + +// SubscriberStatus defines the status of a single subscriber to a Channel. +type SubscriberStatus struct { + // UID is used to understand the origin of the subscriber. + // +optional + UID types.UID `json:"uid,omitempty"` + // Generation of the origin of the subscriber with uid:UID. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + // Status of the subscriber. + // +optional + Ready corev1.ConditionStatus `json:"ready,omitempty"` + // A human readable message indicating details of Ready status. + // +optional + Message string `json:"message,omitempty"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SubscribableType is a skeleton type wrapping Subscribable in the manner we expect resource writers +// defining compatible resources to embed it. We will typically use this type to deserialize +// SubscribableType ObjectReferences and access the Subscription data. This is not a real resource. +type SubscribableType struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // SubscribableTypeSpec is the part where Subscribable object is + // configured as to be compatible with Subscribable contract. + Spec SubscribableTypeSpec `json:"spec"` + + // SubscribableTypeStatus is the part where SubscribableStatus object is + // configured as to be compatible with Subscribable contract. + Status SubscribableTypeStatus `json:"status"` +} + +// SubscribableTypeSpec shows how we expect folks to embed Subscribable in their Spec field. +type SubscribableTypeSpec struct { + Subscribable *Subscribable `json:"subscribable,omitempty"` +} + +// SubscribableTypeStatus shows how we expect folks to embed Subscribable in their Status field. +type SubscribableTypeStatus struct { + DeprecatedSubscribableStatus *SubscribableStatus `json:"subscribablestatus,omitempty"` + SubscribableStatus *SubscribableStatus `json:"subscribableStatus,omitempty"` +} + +var ( + // Verify SubscribableType resources meet duck contracts. + _ duck.Populatable = (*SubscribableType)(nil) + _ apis.Listable = (*SubscribableType)(nil) +) + +// GetSubscribableTypeStatus method Returns the Default SubscribableStatus in this case it's SubscribableStatus +// This is w.r.t https://github.com/knative/eventing/pull/1685#discussion_r314797276 +// Due to change in the API, we support reading of SubscribableTypeStatus#DeprecatedSubscribableStatus in a logical way +// where we read the V2 value first and if the value is absent then we read the V1 value, +// Having this function here makes it convinient to read the default value at runtime. +func (s *SubscribableTypeStatus) GetSubscribableTypeStatus() *SubscribableStatus { + if s.SubscribableStatus == nil { + return s.DeprecatedSubscribableStatus + } + return s.SubscribableStatus + +} + +// SetSubscribableTypeStatus method sets the SubscribableStatus Values in th SubscribableTypeStatus structs +// This helper function ensures that we set both the values (SubscribableStatus and DeprecatedSubscribableStatus) +func (s *SubscribableTypeStatus) SetSubscribableTypeStatus(subscriberStatus SubscribableStatus) { + s.SubscribableStatus = &subscriberStatus + s.DeprecatedSubscribableStatus = &subscriberStatus +} + +// AddSubscriberToSubscribableStatus method is a Helper method for type SubscribableTypeStatus, if Subscribable Status needs to be appended +// with Subscribers, use this function, so that the value is reflected in both the duplicate fields residing +// in SubscribableTypeStatus +func (s *SubscribableTypeStatus) AddSubscriberToSubscribableStatus(subscriberStatus SubscriberStatus) { + subscribers := append(s.GetSubscribableTypeStatus().Subscribers, subscriberStatus) + s.SubscribableStatus.Subscribers = subscribers + s.DeprecatedSubscribableStatus.Subscribers = subscribers +} + +// GetFullType implements duck.Implementable +func (s *Subscribable) GetFullType() duck.Populatable { + return &SubscribableType{} +} + +// Populate implements duck.Populatable +func (c *SubscribableType) Populate() { + c.Spec.Subscribable = &Subscribable{ + // Populate ALL fields + Subscribers: []SubscriberSpec{{ + UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1", + Generation: 1, + SubscriberURI: "call1", + ReplyURI: "sink2", + }, { + UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1", + Generation: 2, + SubscriberURI: "call2", + ReplyURI: "sink2", + }}, + } + c.Status.SetSubscribableTypeStatus(SubscribableStatus{ + // Populate ALL fields + Subscribers: []SubscriberStatus{{ + UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1", + ObservedGeneration: 1, + Ready: corev1.ConditionTrue, + Message: "Some message", + }, { + UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1", + ObservedGeneration: 2, + Ready: corev1.ConditionFalse, + Message: "Some message", + }}, + }) +} + +// GetListType implements apis.Listable +func (c *SubscribableType) GetListType() runtime.Object { + return &SubscribableTypeList{} +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SubscribableTypeList is a list of SubscribableType resources +type SubscribableTypeList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []SubscribableType `json:"items"` +} diff --git a/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..93dcab3ce3 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,500 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelTemplateSpec) DeepCopyInto(out *ChannelTemplateSpec) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.Spec != nil { + in, out := &in.Spec, &out.Spec + *out = new(runtime.RawExtension) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelTemplateSpec. +func (in *ChannelTemplateSpec) DeepCopy() *ChannelTemplateSpec { + if in == nil { + return nil + } + out := new(ChannelTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ChannelTemplateSpec) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelTemplateSpecInternal) DeepCopyInto(out *ChannelTemplateSpecInternal) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Spec != nil { + in, out := &in.Spec, &out.Spec + *out = new(runtime.RawExtension) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelTemplateSpecInternal. +func (in *ChannelTemplateSpecInternal) DeepCopy() *ChannelTemplateSpecInternal { + if in == nil { + return nil + } + out := new(ChannelTemplateSpecInternal) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ChannelTemplateSpecInternal) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Channelable) DeepCopyInto(out *Channelable) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Channelable. +func (in *Channelable) DeepCopy() *Channelable { + if in == nil { + return nil + } + out := new(Channelable) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Channelable) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelableList) DeepCopyInto(out *ChannelableList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Channelable, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelableList. +func (in *ChannelableList) DeepCopy() *ChannelableList { + if in == nil { + return nil + } + out := new(ChannelableList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ChannelableList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelableSpec) DeepCopyInto(out *ChannelableSpec) { + *out = *in + in.SubscribableTypeSpec.DeepCopyInto(&out.SubscribableTypeSpec) + if in.Delivery != nil { + in, out := &in.Delivery, &out.Delivery + *out = new(DeliverySpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelableSpec. +func (in *ChannelableSpec) DeepCopy() *ChannelableSpec { + if in == nil { + return nil + } + out := new(ChannelableSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelableStatus) DeepCopyInto(out *ChannelableStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + in.AddressStatus.DeepCopyInto(&out.AddressStatus) + in.SubscribableTypeStatus.DeepCopyInto(&out.SubscribableTypeStatus) + if in.ErrorChannel != nil { + in, out := &in.ErrorChannel, &out.ErrorChannel + *out = new(v1.ObjectReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelableStatus. +func (in *ChannelableStatus) DeepCopy() *ChannelableStatus { + if in == nil { + return nil + } + out := new(ChannelableStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeliverySpec) DeepCopyInto(out *DeliverySpec) { + *out = *in + if in.DeadLetterSink != nil { + in, out := &in.DeadLetterSink, &out.DeadLetterSink + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + if in.Retry != nil { + in, out := &in.Retry, &out.Retry + *out = new(int32) + **out = **in + } + if in.BackoffPolicy != nil { + in, out := &in.BackoffPolicy, &out.BackoffPolicy + *out = new(BackoffPolicyType) + **out = **in + } + if in.BackoffDelay != nil { + in, out := &in.BackoffDelay, &out.BackoffDelay + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeliverySpec. +func (in *DeliverySpec) DeepCopy() *DeliverySpec { + if in == nil { + return nil + } + out := new(DeliverySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeliveryStatus) DeepCopyInto(out *DeliveryStatus) { + *out = *in + if in.DeadLetterChannel != nil { + in, out := &in.DeadLetterChannel, &out.DeadLetterChannel + *out = new(v1.ObjectReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeliveryStatus. +func (in *DeliveryStatus) DeepCopy() *DeliveryStatus { + if in == nil { + return nil + } + out := new(DeliveryStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Resource) DeepCopyInto(out *Resource) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resource. +func (in *Resource) DeepCopy() *Resource { + if in == nil { + return nil + } + out := new(Resource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Resource) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceList) DeepCopyInto(out *ResourceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Resource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceList. +func (in *ResourceList) DeepCopy() *ResourceList { + if in == nil { + return nil + } + out := new(ResourceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Subscribable) DeepCopyInto(out *Subscribable) { + *out = *in + if in.Subscribers != nil { + in, out := &in.Subscribers, &out.Subscribers + *out = make([]SubscriberSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subscribable. +func (in *Subscribable) DeepCopy() *Subscribable { + if in == nil { + return nil + } + out := new(Subscribable) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscribableStatus) DeepCopyInto(out *SubscribableStatus) { + *out = *in + if in.Subscribers != nil { + in, out := &in.Subscribers, &out.Subscribers + *out = make([]SubscriberStatus, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscribableStatus. +func (in *SubscribableStatus) DeepCopy() *SubscribableStatus { + if in == nil { + return nil + } + out := new(SubscribableStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscribableType) DeepCopyInto(out *SubscribableType) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscribableType. +func (in *SubscribableType) DeepCopy() *SubscribableType { + if in == nil { + return nil + } + out := new(SubscribableType) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SubscribableType) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscribableTypeList) DeepCopyInto(out *SubscribableTypeList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SubscribableType, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscribableTypeList. +func (in *SubscribableTypeList) DeepCopy() *SubscribableTypeList { + if in == nil { + return nil + } + out := new(SubscribableTypeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SubscribableTypeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscribableTypeSpec) DeepCopyInto(out *SubscribableTypeSpec) { + *out = *in + if in.Subscribable != nil { + in, out := &in.Subscribable, &out.Subscribable + *out = new(Subscribable) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscribableTypeSpec. +func (in *SubscribableTypeSpec) DeepCopy() *SubscribableTypeSpec { + if in == nil { + return nil + } + out := new(SubscribableTypeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscribableTypeStatus) DeepCopyInto(out *SubscribableTypeStatus) { + *out = *in + if in.DeprecatedSubscribableStatus != nil { + in, out := &in.DeprecatedSubscribableStatus, &out.DeprecatedSubscribableStatus + *out = new(SubscribableStatus) + (*in).DeepCopyInto(*out) + } + if in.SubscribableStatus != nil { + in, out := &in.SubscribableStatus, &out.SubscribableStatus + *out = new(SubscribableStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscribableTypeStatus. +func (in *SubscribableTypeStatus) DeepCopy() *SubscribableTypeStatus { + if in == nil { + return nil + } + out := new(SubscribableTypeStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriberSpec) DeepCopyInto(out *SubscriberSpec) { + *out = *in + if in.DeprecatedRef != nil { + in, out := &in.DeprecatedRef, &out.DeprecatedRef + *out = new(v1.ObjectReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriberSpec. +func (in *SubscriberSpec) DeepCopy() *SubscriberSpec { + if in == nil { + return nil + } + out := new(SubscriberSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriberStatus) DeepCopyInto(out *SubscriberStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriberStatus. +func (in *SubscriberStatus) DeepCopy() *SubscriberStatus { + if in == nil { + return nil + } + out := new(SubscriberStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/register.go b/vendor/knative.dev/eventing/pkg/apis/eventing/register.go new file mode 100644 index 0000000000..49493ed577 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/register.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 The Knative 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 eventing + +const ( + GroupName = "eventing.knative.dev" +) diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_defaults.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_defaults.go new file mode 100644 index 0000000000..fabd340d32 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_defaults.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" +) + +func (b *Broker) SetDefaults(ctx context.Context) { + // If we haven't configured the new channelTemplate, + // then set the default channel to the new channelTemplate. + if b != nil && b.Spec.ChannelTemplate == nil { + // The singleton may not have been set, if so ignore it and validation will reject the Broker. + if cd := eventingduckv1alpha1.ChannelDefaulterSingleton; cd != nil { + channelTemplate := cd.GetDefault(b.Namespace) + b.Spec.ChannelTemplate = channelTemplate + } + } + b.Spec.SetDefaults(ctx) +} + +func (bs *BrokerSpec) SetDefaults(ctx context.Context) { + // None +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_lifecycle.go new file mode 100644 index 0000000000..8b45d15958 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_lifecycle.go @@ -0,0 +1,155 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + appsv1 "k8s.io/api/apps/v1" + "knative.dev/pkg/apis" + + "knative.dev/eventing/pkg/apis/duck" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" +) + +var brokerCondSet = apis.NewLivingConditionSet( + BrokerConditionIngress, + BrokerConditionTriggerChannel, + BrokerConditionIngressChannel, + BrokerConditionFilter, + BrokerConditionAddressable, + BrokerConditionIngressSubscription, +) + +const ( + BrokerConditionReady = apis.ConditionReady + BrokerConditionIngress apis.ConditionType = "IngressReady" + + BrokerConditionTriggerChannel apis.ConditionType = "TriggerChannelReady" + + BrokerConditionIngressChannel apis.ConditionType = "IngressChannelReady" + + BrokerConditionIngressSubscription apis.ConditionType = "IngressSubscriptionReady" + + BrokerConditionFilter apis.ConditionType = "FilterReady" + + BrokerConditionAddressable apis.ConditionType = "Addressable" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (bs *BrokerStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return brokerCondSet.Manage(bs).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (bs *BrokerStatus) IsReady() bool { + return brokerCondSet.Manage(bs).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (bs *BrokerStatus) InitializeConditions() { + brokerCondSet.Manage(bs).InitializeConditions() +} + +func (bs *BrokerStatus) MarkIngressFailed(reason, format string, args ...interface{}) { + brokerCondSet.Manage(bs).MarkFalse(BrokerConditionIngress, reason, format, args...) +} + +func (bs *BrokerStatus) PropagateIngressDeploymentAvailability(d *appsv1.Deployment) { + if duck.DeploymentIsAvailable(&d.Status, true) { + brokerCondSet.Manage(bs).MarkTrue(BrokerConditionIngress) + } else { + // I don't know how to propagate the status well, so just give the name of the Deployment + // for now. + bs.MarkIngressFailed("DeploymentUnavailable", "The Deployment '%s' is unavailable.", d.Name) + } +} + +func (bs *BrokerStatus) MarkTriggerChannelFailed(reason, format string, args ...interface{}) { + brokerCondSet.Manage(bs).MarkFalse(BrokerConditionTriggerChannel, reason, format, args...) +} + +func (bs *BrokerStatus) PropagateTriggerChannelReadiness(cs *duckv1alpha1.ChannelableStatus) { + // TODO: Once you can get a Ready status from Channelable in a generic way, use it here... + address := cs.AddressStatus.Address + if address != nil { + brokerCondSet.Manage(bs).MarkTrue(BrokerConditionTriggerChannel) + } else { + bs.MarkTriggerChannelFailed("ChannelNotReady", "trigger Channel is not ready: not addressalbe") + } +} + +func (bs *BrokerStatus) MarkIngressChannelFailed(reason, format string, args ...interface{}) { + brokerCondSet.Manage(bs).MarkFalse(BrokerConditionIngressChannel, reason, format, args...) +} + +func (bs *BrokerStatus) PropagateIngressChannelReadiness(cs *duckv1alpha1.ChannelableStatus) { + // TODO: Once you can get a Ready status from Channelable in a generic way, use it here... + address := cs.AddressStatus.Address + if address != nil { + brokerCondSet.Manage(bs).MarkTrue(BrokerConditionIngressChannel) + } else { + bs.MarkIngressChannelFailed("ChannelNotReady", "ingress Channel is not ready: not addressable") + } +} + +func (bs *BrokerStatus) MarkIngressSubscriptionFailed(reason, format string, args ...interface{}) { + brokerCondSet.Manage(bs).MarkFalse(BrokerConditionIngressSubscription, reason, format, args...) +} + +func (bs *BrokerStatus) MarkIngressSubscriptionNotOwned(sub *messagingv1alpha1.Subscription) { + bs.MarkIngressSubscriptionFailed("SubscriptionNotOwned", "Subscription %q is not owned by this Broker.", sub.Name) +} + +func (bs *BrokerStatus) PropagateIngressSubscriptionReadiness(ss *messagingv1alpha1.SubscriptionStatus) { + if ss.IsReady() { + brokerCondSet.Manage(bs).MarkTrue(BrokerConditionIngressSubscription) + } else { + msg := "nil" + if sc := ss.GetCondition(messagingv1alpha1.SubscriptionConditionReady); sc != nil { + msg = sc.Message + } + bs.MarkIngressSubscriptionFailed("SubscriptionNotReady", "ingress Subscription is not ready: %s", msg) + } +} + +func (bs *BrokerStatus) MarkFilterFailed(reason, format string, args ...interface{}) { + brokerCondSet.Manage(bs).MarkFalse(BrokerConditionFilter, reason, format, args...) +} + +func (bs *BrokerStatus) PropagateFilterDeploymentAvailability(d *appsv1.Deployment) { + if duck.DeploymentIsAvailable(&d.Status, true) { + brokerCondSet.Manage(bs).MarkTrue(BrokerConditionFilter) + } else { + // I don't know how to propagate the status well, so just give the name of the Deployment + // for now. + bs.MarkFilterFailed("DeploymentUnavailable", "The Deployment '%s' is unavailable.", d.Name) + } +} + +// SetAddress makes this Broker addressable by setting the hostname. It also +// sets the BrokerConditionAddressable to true. +func (bs *BrokerStatus) SetAddress(url *apis.URL) { + if url != nil { + bs.Address.Hostname = url.Host + bs.Address.URL = url + brokerCondSet.Manage(bs).MarkTrue(BrokerConditionAddressable) + } else { + bs.Address.Hostname = "" + bs.Address.URL = nil + brokerCondSet.Manage(bs).MarkFalse(BrokerConditionAddressable, "emptyHostname", "hostname is the empty string") + } +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_types.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_types.go new file mode 100644 index 0000000000..f650da4243 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_types.go @@ -0,0 +1,117 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/webhook" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Broker collects a pool of events that are consumable using Triggers. Brokers +// provide a well-known endpoint for event delivery that senders can use with +// minimal knowledge of the event routing strategy. Receivers use Triggers to +// request delivery of events from a Broker's pool to a specific URL or +// Addressable endpoint. +type Broker struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the Broker. + Spec BrokerSpec `json:"spec,omitempty"` + + // Status represents the current state of the Broker. This data may be out of + // date. + // +optional + Status BrokerStatus `json:"status,omitempty"` +} + +var ( + // Check that Broker can be validated, can be defaulted, and has immutable fields. + _ apis.Validatable = (*Broker)(nil) + _ apis.Defaultable = (*Broker)(nil) + _ apis.Immutable = (*Broker)(nil) + + // Check that Broker can return its spec untyped. + _ apis.HasSpec = (*Broker)(nil) + + _ runtime.Object = (*Broker)(nil) + _ webhook.GenericCRD = (*Broker)(nil) + + // Check that we can create OwnerReferences to a Broker. + _ kmeta.OwnerRefable = (*Broker)(nil) +) + +type BrokerSpec struct { + // ChannelTemplate specifies which Channel CRD to use to create all the Channels used internally by the + // Broker. If left unspecified, it is set to the default Channel CRD for the namespace (or cluster, in case there + // are no defaults for the namespace). + // +optional + ChannelTemplate *eventingduckv1alpha1.ChannelTemplateSpec `json:"channelTemplateSpec,omitempty"` +} + +// BrokerStatus represents the current state of a Broker. +type BrokerStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // Broker is Addressable. It currently exposes the endpoint as a + // fully-qualified DNS name which will distribute traffic over the + // provided targets from inside the cluster. + // + // It generally has the form {broker}-router.{namespace}.svc.{cluster domain name} + Address duckv1alpha1.Addressable `json:"address,omitempty"` + + // TriggerChannel is an objectref to the object for the TriggerChannel + TriggerChannel *corev1.ObjectReference `json:"triggerChannel,omitempty"` + + // IngressChannel is an objectref to the object for the IngressChannel + IngressChannel *corev1.ObjectReference `json:"IngressChannel,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// BrokerList is a collection of Brokers. +type BrokerList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []Broker `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for Brokers +func (t *Broker) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Broker") +} + +// GetUntypedSpec returns the spec of the Broker. +func (b *Broker) GetUntypedSpec() interface{} { + return b.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_validation.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_validation.go new file mode 100644 index 0000000000..837091e9b4 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/broker_validation.go @@ -0,0 +1,81 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + "knative.dev/pkg/kmp" +) + +func (b *Broker) Validate(ctx context.Context) *apis.FieldError { + return b.Spec.Validate(ctx).ViaField("spec") +} + +func (bs *BrokerSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + + // Validate the new channelTemplate. + if cte := isValidChannelTemplate(bs.ChannelTemplate); cte != nil { + errs = errs.Also(cte.ViaField("channelTemplateSpec")) + } + + // TODO validate that the channelTemplate only specifies the provisioner and arguments. + return errs +} + +func isValidChannelTemplate(dct *eventingduckv1alpha1.ChannelTemplateSpec) *apis.FieldError { + var errs *apis.FieldError + if dct == nil { + return nil + } + if dct.Kind == "" { + errs = errs.Also(apis.ErrMissingField("kind")) + } + if dct.APIVersion == "" { + errs = errs.Also(apis.ErrMissingField("apiVersion")) + } + return errs +} + +func (b *Broker) CheckImmutableFields(ctx context.Context, og apis.Immutable) *apis.FieldError { + if og == nil { + return nil + } + original, ok := og.(*Broker) + if !ok { + return &apis.FieldError{Message: "The provided original was not a Broker"} + } + + if diff, err := kmp.ShortDiff(original.Spec.ChannelTemplate, b.Spec.ChannelTemplate); err != nil { + return &apis.FieldError{ + Message: "Failed to diff Broker", + Paths: []string{"spec"}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec", "channelTemplate"}, + Details: diff, + } + } + + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/doc.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/doc.go new file mode 100644 index 0000000000..1b017951a8 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 is the v1alpha1 version of the API. +// +k8s:deepcopy-gen=package +// +groupName=eventing.knative.dev +package v1alpha1 diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_defaults.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_defaults.go new file mode 100644 index 0000000000..eee2cec8c4 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_defaults.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 The Knative 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 v1alpha1 + +import "context" + +func (et *EventType) SetDefaults(ctx context.Context) { + et.Spec.SetDefaults(ctx) +} + +func (ets *EventTypeSpec) SetDefaults(ctx context.Context) { + if ets.Broker == "" { + ets.Broker = "default" + } +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_lifecycle.go new file mode 100644 index 0000000000..6783fb3681 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_lifecycle.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "knative.dev/pkg/apis" +) + +var eventTypeCondSet = apis.NewLivingConditionSet(EventTypeConditionBrokerExists, EventTypeConditionBrokerReady) + +const ( + EventTypeConditionReady = apis.ConditionReady + EventTypeConditionBrokerExists apis.ConditionType = "BrokerExists" + EventTypeConditionBrokerReady apis.ConditionType = "BrokerReady" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (et *EventTypeStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return eventTypeCondSet.Manage(et).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (et *EventTypeStatus) IsReady() bool { + return eventTypeCondSet.Manage(et).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (et *EventTypeStatus) InitializeConditions() { + eventTypeCondSet.Manage(et).InitializeConditions() +} + +func (et *EventTypeStatus) MarkBrokerExists() { + eventTypeCondSet.Manage(et).MarkTrue(EventTypeConditionBrokerExists) +} + +func (et *EventTypeStatus) MarkBrokerDoesNotExist() { + eventTypeCondSet.Manage(et).MarkFalse(EventTypeConditionBrokerExists, "BrokerDoesNotExist", "Broker does not exist") +} + +func (et *EventTypeStatus) MarkBrokerReady() { + eventTypeCondSet.Manage(et).MarkTrue(EventTypeConditionBrokerReady) +} + +func (et *EventTypeStatus) MarkBrokerNotReady() { + eventTypeCondSet.Manage(et).MarkFalse(EventTypeConditionBrokerReady, "BrokerNotReady", "Broker is not ready") +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_types.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_types.go new file mode 100644 index 0000000000..67a0179ab1 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_types.go @@ -0,0 +1,104 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/webhook" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type EventType struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the EventType. + Spec EventTypeSpec `json:"spec,omitempty"` + + // Status represents the current state of the EventType. + // This data may be out of date. + // +optional + Status EventTypeStatus `json:"status,omitempty"` +} + +var ( + // Check that EventType can be validated, can be defaulted, and has immutable fields. + _ apis.Validatable = (*EventType)(nil) + _ apis.Defaultable = (*EventType)(nil) + _ apis.Immutable = (*EventType)(nil) + + // Check that EventType can return its spec untyped. + _ apis.HasSpec = (*EventType)(nil) + + _ runtime.Object = (*EventType)(nil) + _ webhook.GenericCRD = (*EventType)(nil) + + // Check that we can create OwnerReferences to an EventType. + _ kmeta.OwnerRefable = (*EventType)(nil) +) + +type EventTypeSpec struct { + // Type represents the CloudEvents type. It is authoritative. + Type string `json:"type"` + // Source is a URI, it represents the CloudEvents source. + Source string `json:"source"` + // Schema is a URI, it represents the CloudEvents schemaurl extension attribute. + // It may be a JSON schema, a protobuf schema, etc. It is optional. + // +optional + Schema string `json:"schema,omitempty"` + // Broker refers to the Broker that can provide the EventType. + Broker string `json:"broker"` + // Description is an optional field used to describe the EventType, in any meaningful way. + // +optional + Description string `json:"description,omitempty"` +} + +// EventTypeStatus represents the current state of a EventType. +type EventTypeStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// EventTypeList is a collection of EventTypes. +type EventTypeList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []EventType `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for EventType +func (p *EventType) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("EventType") +} + +// GetUntypedSpec returns the spec of the EventType. +func (e *EventType) GetUntypedSpec() interface{} { + return e.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_validation.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_validation.go new file mode 100644 index 0000000000..83efc7594f --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/eventtype_validation.go @@ -0,0 +1,77 @@ +/* +Copyright 2018 The Knative 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 v1alpha1 + +import ( + "context" + + "github.com/google/go-cmp/cmp/cmpopts" + + "knative.dev/pkg/apis" + "knative.dev/pkg/kmp" +) + +func (et *EventType) Validate(ctx context.Context) *apis.FieldError { + return et.Spec.Validate(ctx).ViaField("spec") +} + +func (ets *EventTypeSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + if ets.Type == "" { + fe := apis.ErrMissingField("type") + errs = errs.Also(fe) + } + if ets.Source == "" { + // TODO validate is a valid URI. + fe := apis.ErrMissingField("source") + errs = errs.Also(fe) + } + if ets.Broker == "" { + fe := apis.ErrMissingField("broker") + errs = errs.Also(fe) + } + // TODO validate Schema is a valid URI. + return errs +} + +func (et *EventType) CheckImmutableFields(ctx context.Context, og apis.Immutable) *apis.FieldError { + if og == nil { + return nil + } + + original, ok := og.(*EventType) + if !ok { + return &apis.FieldError{Message: "The provided original was not an EventType"} + } + + // All but Description field immutable. + ignoreArguments := cmpopts.IgnoreFields(EventTypeSpec{}, "Description") + if diff, err := kmp.ShortDiff(original.Spec, et.Spec, ignoreArguments); err != nil { + return &apis.FieldError{ + Message: "Failed to diff EventType", + Paths: []string{"spec"}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec"}, + Details: diff, + } + } + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/register.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/register.go new file mode 100644 index 0000000000..df3a64fb91 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/register.go @@ -0,0 +1,57 @@ +/* +Copyright 2018 The Knative 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 v1alpha1 + +import ( + "knative.dev/eventing/pkg/apis/eventing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: eventing.GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &Broker{}, + &BrokerList{}, + &EventType{}, + &EventTypeList{}, + &Trigger{}, + &TriggerList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/test_helper.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/test_helper.go new file mode 100644 index 0000000000..ffbf04a18c --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/test_helper.go @@ -0,0 +1,117 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + v1 "k8s.io/api/apps/v1" + "knative.dev/pkg/apis" + pkgduckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" + duckv1 "knative.dev/pkg/apis/duck/v1" + duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" +) + +type testHelper struct{} + +// TestHelper contains helpers for unit tests. +var TestHelper = testHelper{} + +func (testHelper) ReadyChannelStatus() *duckv1alpha1.ChannelableStatus { + cs := &duckv1alpha1.ChannelableStatus{ + Status: duckv1.Status{}, + AddressStatus: pkgduckv1alpha1.AddressStatus{ + Address: &pkgduckv1alpha1.Addressable{ + Addressable: duckv1beta1.Addressable{ + URL: &apis.URL{Scheme: "http", Host: "foo"}, + }, + Hostname: "foo", + }, + }, + SubscribableTypeStatus: duckv1alpha1.SubscribableTypeStatus{}} + return cs +} + +func (t testHelper) NotReadyChannelStatus() *duckv1alpha1.ChannelableStatus { + return &duckv1alpha1.ChannelableStatus{} +} + +func (testHelper) ReadySubscriptionStatus() *messagingv1alpha1.SubscriptionStatus { + ss := &messagingv1alpha1.SubscriptionStatus{} + ss.MarkChannelReady() + ss.MarkReferencesResolved() + ss.MarkAddedToChannel() + return ss +} + +func (testHelper) NotReadySubscriptionStatus() *messagingv1alpha1.SubscriptionStatus { + ss := &messagingv1alpha1.SubscriptionStatus{} + ss.MarkReferencesResolved() + ss.MarkChannelNotReady("testInducedError", "test induced %s", "error") + return ss +} + +func (t testHelper) ReadyBrokerStatus() *BrokerStatus { + bs := &BrokerStatus{} + bs.PropagateIngressDeploymentAvailability(t.AvailableDeployment()) + bs.PropagateIngressChannelReadiness(t.ReadyChannelStatus()) + bs.PropagateTriggerChannelReadiness(t.ReadyChannelStatus()) + bs.PropagateIngressSubscriptionReadiness(t.ReadySubscriptionStatus()) + bs.PropagateFilterDeploymentAvailability(t.AvailableDeployment()) + bs.SetAddress(&apis.URL{Scheme: "http", Host: "foo"}) + return bs +} + +func (t testHelper) NotReadyBrokerStatus() *BrokerStatus { + bs := &BrokerStatus{} + bs.PropagateIngressChannelReadiness(&duckv1alpha1.ChannelableStatus{}) + return bs +} + +func (t testHelper) ReadyTriggerStatus() *TriggerStatus { + ts := &TriggerStatus{} + ts.InitializeConditions() + ts.SubscriberURI = "http://foo/" + ts.PropagateBrokerStatus(t.ReadyBrokerStatus()) + ts.PropagateSubscriptionStatus(t.ReadySubscriptionStatus()) + return ts +} + +func (testHelper) UnavailableDeployment() *v1.Deployment { + d := &v1.Deployment{} + d.Name = "unavailable" + d.Status.Conditions = []v1.DeploymentCondition{ + { + Type: v1.DeploymentAvailable, + Status: "False", + }, + } + return d +} + +func (t testHelper) AvailableDeployment() *v1.Deployment { + d := t.UnavailableDeployment() + d.Name = "available" + d.Status.Conditions = []v1.DeploymentCondition{ + { + Type: v1.DeploymentAvailable, + Status: "True", + }, + } + return d +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_defaults.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_defaults.go new file mode 100644 index 0000000000..921192e583 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_defaults.go @@ -0,0 +1,47 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" +) + +const ( + brokerLabel = "eventing.knative.dev/broker" +) + +func (t *Trigger) SetDefaults(ctx context.Context) { + t.Spec.SetDefaults(ctx) + setLabels(t) +} + +func (ts *TriggerSpec) SetDefaults(ctx context.Context) { + if ts.Broker == "" { + ts.Broker = "default" + } + // Make a default filter that allows anything. + if ts.Filter == nil { + ts.Filter = &TriggerFilter{} + } +} + +func setLabels(t *Trigger) { + if len(t.Labels) == 0 { + t.Labels = map[string]string{} + } + t.Labels[brokerLabel] = t.Spec.Broker +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_lifecycle.go new file mode 100644 index 0000000000..7c75d5af03 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_lifecycle.go @@ -0,0 +1,115 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" + "knative.dev/pkg/apis" + duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" +) + +var triggerCondSet = apis.NewLivingConditionSet(TriggerConditionBroker, TriggerConditionSubscribed, TriggerConditionDependency) + +const ( + // TriggerConditionReady has status True when all subconditions below have been set to True. + TriggerConditionReady = apis.ConditionReady + + TriggerConditionBroker apis.ConditionType = "Broker" + + TriggerConditionSubscribed apis.ConditionType = "Subscribed" + + TriggerConditionDependency apis.ConditionType = "Dependency" + + // TriggerAnyFilter Constant to represent that we should allow anything. + TriggerAnyFilter = "" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (ts *TriggerStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return triggerCondSet.Manage(ts).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (ts *TriggerStatus) IsReady() bool { + return triggerCondSet.Manage(ts).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (ts *TriggerStatus) InitializeConditions() { + triggerCondSet.Manage(ts).InitializeConditions() +} + +func (ts *TriggerStatus) PropagateBrokerStatus(bs *BrokerStatus) { + if bs.IsReady() { + triggerCondSet.Manage(ts).MarkTrue(TriggerConditionBroker) + } else { + msg := "nil" + if bc := brokerCondSet.Manage(bs).GetCondition(BrokerConditionReady); bc != nil { + msg = bc.Message + } + ts.MarkBrokerFailed("BrokerNotReady", "Broker is not ready: %s", msg) + } +} + +func (ts *TriggerStatus) MarkBrokerFailed(reason, messageFormat string, messageA ...interface{}) { + triggerCondSet.Manage(ts).MarkFalse(TriggerConditionBroker, reason, messageFormat, messageA...) +} + +func (ts *TriggerStatus) PropagateSubscriptionStatus(ss *messagingv1alpha1.SubscriptionStatus) { + if ss.IsReady() { + triggerCondSet.Manage(ts).MarkTrue(TriggerConditionSubscribed) + } else { + msg := "nil" + if sc := ss.Status.GetCondition(messagingv1alpha1.SubscriptionConditionReady); sc != nil { + msg = sc.Message + } + ts.MarkNotSubscribed("SubscriptionNotReady", "Subscription is not ready: %s", msg) + } +} + +func (ts *TriggerStatus) MarkNotSubscribed(reason, messageFormat string, messageA ...interface{}) { + triggerCondSet.Manage(ts).MarkFalse(TriggerConditionSubscribed, reason, messageFormat, messageA...) +} + +func (ts *TriggerStatus) MarkSubscriptionNotOwned(sub *messagingv1alpha1.Subscription) { + triggerCondSet.Manage(ts).MarkFalse(TriggerConditionSubscribed, "SubscriptionNotOwned", "Subscription %q is not owned by this Trigger.", sub.Name) +} + +func (ts *TriggerStatus) MarkDependencySucceeded() { + triggerCondSet.Manage(ts).MarkTrue(TriggerConditionDependency) +} + +func (ts *TriggerStatus) MarkDependencyFailed(reason, messageFormat string, messageA ...interface{}) { + triggerCondSet.Manage(ts).MarkFalse(TriggerConditionDependency, reason, messageFormat, messageA...) +} + +func (ts *TriggerStatus) MarkDependencyUnknown(reason, messageFormat string, messageA ...interface{}) { + triggerCondSet.Manage(ts).MarkUnknown(TriggerConditionDependency, reason, messageFormat, messageA...) +} + +func (ts *TriggerStatus) PropagateDependencyStatus(ks *duckv1alpha1.KResource) { + kc := ks.Status.GetCondition(duckv1alpha1.ConditionReady) + if kc != nil && kc.IsTrue() { + ts.MarkDependencySucceeded() + } else { + msg := "nil" + if kc != nil { + msg = kc.Message + } + ts.MarkDependencyFailed("DependencyNotReady", "Dependency is not ready: %s", msg) + } +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_types.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_types.go new file mode 100644 index 0000000000..97669f601e --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_types.go @@ -0,0 +1,151 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/webhook" +) + +const ( + // DependencyAnnotation is the annotation key used to mark the sources that the Trigger depends on. + // This will be used when the kn client creates an importer and trigger pair for the user such that the trigger only receives events produced by the paired importer. + DependencyAnnotation = "knative.dev/dependency" + // InjectionAnnotation is the annotation key used to enable knative eventing injection for a namespace and automatically create a default broker. + // This will be used when the client creates a trigger paired with default broker and the default broker doesn't exist in the namespace + InjectionAnnotation = "knative-eventing-injection" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Trigger represents a request to have events delivered to a consumer from a +// Broker's event pool. +type Trigger struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the Trigger. + Spec TriggerSpec `json:"spec,omitempty"` + + // Status represents the current state of the Trigger. This data may be out of + // date. + // +optional + Status TriggerStatus `json:"status,omitempty"` +} + +var ( + // Check that Trigger can be validated, can be defaulted, and has immutable fields. + _ apis.Validatable = (*Trigger)(nil) + _ apis.Defaultable = (*Trigger)(nil) + _ apis.Immutable = (*Trigger)(nil) + + // Check that Trigger can return its spec untyped. + _ apis.HasSpec = (*Trigger)(nil) + + _ runtime.Object = (*Trigger)(nil) + _ webhook.GenericCRD = (*Trigger)(nil) + + // Check that we can create OwnerReferences to a Trigger. + _ kmeta.OwnerRefable = (*Trigger)(nil) +) + +type TriggerSpec struct { + // Broker is the broker that this trigger receives events from. If not specified, will default + // to 'default'. + Broker string `json:"broker,omitempty"` + + // Filter is the filter to apply against all events from the Broker. Only events that pass this + // filter will be sent to the Subscriber. If not specified, will default to allowing all events. + // + // +optional + Filter *TriggerFilter `json:"filter,omitempty"` + + // Subscriber is the addressable that receives events from the Broker that pass the Filter. It + // is required. + Subscriber *apisv1alpha1.Destination `json:"subscriber,omitempty"` +} + +type TriggerFilter struct { + // DeprecatedSourceAndType filters events based on exact matches on the + // CloudEvents type and source attributes. This field has been replaced by the + // Attributes field. + // + // +optional + DeprecatedSourceAndType *TriggerFilterSourceAndType `json:"sourceAndType,omitempty"` + + // Attributes filters events by exact match on event context attributes. + // Each key in the map is compared with the equivalent key in the event + // context. An event passes the filter if all values are equal to the + // specified values. + // + // Nested context attributes are not supported as keys. Only string values are supported. + // + // +optional + Attributes *TriggerFilterAttributes `json:"attributes,omitempty"` +} + +// TriggerFilterSourceAndType filters events based on exact matches on the cloud event's type and +// source attributes. Only exact matches will pass the filter. Either or both type and source can +// use the value '' to indicate all strings match. +type TriggerFilterSourceAndType struct { + Type string `json:"type,omitempty"` + Source string `json:"source,omitempty"` +} + +// TriggerFilterAttributes is a map of context attribute names to values for +// filtering by equality. Only exact matches will pass the filter. You can use the value '' +// to indicate all strings match. +type TriggerFilterAttributes map[string]string + +// TriggerStatus represents the current state of a Trigger. +type TriggerStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // SubscriberURI is the resolved URI of the receiver for this Trigger. + SubscriberURI string `json:"subscriberURI,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TriggerList is a collection of Triggers. +type TriggerList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []Trigger `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for Triggers +func (t *Trigger) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Trigger") +} + +// GetUntypedSpec returns the spec of the Trigger. +func (t *Trigger) GetUntypedSpec() interface{} { + return t.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_validation.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_validation.go new file mode 100644 index 0000000000..38ec543340 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/trigger_validation.go @@ -0,0 +1,191 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + "encoding/json" + "fmt" + "regexp" + + "knative.dev/pkg/apis" + "knative.dev/pkg/kmp" + + corev1 "k8s.io/api/core/v1" +) + +var ( + // Only allow lowercase alphanumeric, starting with letters. + validAttributeName = regexp.MustCompile(`^[a-z][a-z0-9]*$`) +) + +// Validate the Trigger. +func (t *Trigger) Validate(ctx context.Context) *apis.FieldError { + errs := t.Spec.Validate(ctx).ViaField("spec") + errs = t.validateAnnotation(errs, DependencyAnnotation, t.validateDependencyAnnotation) + errs = t.validateAnnotation(errs, InjectionAnnotation, t.validateInjectionAnnotation) + return errs +} + +// Validate the TriggerSpec. +func (ts *TriggerSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + if ts.Broker == "" { + fe := apis.ErrMissingField("broker") + errs = errs.Also(fe) + } + + if ts.Filter == nil { + fe := apis.ErrMissingField("filter") + errs = errs.Also(fe) + } + + if ts.Filter != nil { + filtersSpecified := make([]string, 0) + + if ts.Filter.DeprecatedSourceAndType != nil { + filtersSpecified = append(filtersSpecified, "filter.sourceAndType") + } + + if ts.Filter.Attributes != nil { + filtersSpecified = append(filtersSpecified, "filter.attributes") + if len(*ts.Filter.Attributes) == 0 { + fe := &apis.FieldError{ + Message: "At least one filtered attribute must be specified", + Paths: []string{"filter.attributes"}, + } + errs = errs.Also(fe) + } else { + attrs := map[string]string(*ts.Filter.Attributes) + for attr := range attrs { + if !validAttributeName.MatchString(attr) { + fe := &apis.FieldError{ + Message: fmt.Sprintf("Invalid attribute name: %q", attr), + Paths: []string{"filter.attributes"}, + } + errs = errs.Also(fe) + } + } + } + } + + if len(filtersSpecified) > 1 { + fe := apis.ErrMultipleOneOf(filtersSpecified...) + errs = errs.Also(fe) + } + } + + if ts.Subscriber == nil { + fe := apis.ErrMissingField("subscriber") + errs = errs.Also(fe) + } else if fe := ts.Subscriber.ValidateDisallowDeprecated(ctx); fe != nil { + errs = errs.Also(fe.ViaField("subscriber")) + } + + return errs +} + +// CheckImmutableFields checks that any immutable fields were not changed. +func (t *Trigger) CheckImmutableFields(ctx context.Context, og apis.Immutable) *apis.FieldError { + if og == nil { + return nil + } + + original, ok := og.(*Trigger) + if !ok { + return &apis.FieldError{Message: "The provided original was not a Trigger"} + } + + if diff, err := kmp.ShortDiff(original.Spec.Broker, t.Spec.Broker); err != nil { + return &apis.FieldError{ + Message: "Failed to diff Trigger", + Paths: []string{"spec"}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec", "broker"}, + Details: diff, + } + } + return nil +} + +func GetObjRefFromDependencyAnnotation(dependencyAnnotation string) (corev1.ObjectReference, error) { + var objectRef corev1.ObjectReference + if err := json.Unmarshal([]byte(dependencyAnnotation), &objectRef); err != nil { + return objectRef, err + } + return objectRef, nil +} + +func (t *Trigger) validateAnnotation(errs *apis.FieldError, annotation string, function func(string) *apis.FieldError) *apis.FieldError { + if annotationValue, ok := t.GetAnnotations()[annotation]; ok { + annotationPrefix := fmt.Sprintf("metadata.annotations[%s]", annotation) + errs = errs.Also(function(annotationValue).ViaField(annotationPrefix)) + } + return errs +} + +func (t *Trigger) validateDependencyAnnotation(dependencyAnnotation string) *apis.FieldError { + depObjRef, err := GetObjRefFromDependencyAnnotation(dependencyAnnotation) + if err != nil { + return &apis.FieldError{ + Message: fmt.Sprintf("The provided annotation was not a corev1.ObjectReference: %q", dependencyAnnotation), + Details: err.Error(), + Paths: []string{""}, + } + } + var errs *apis.FieldError + if depObjRef.Namespace != "" && depObjRef.Namespace != t.GetNamespace() { + fe := &apis.FieldError{ + Message: fmt.Sprintf("Namespace must be empty or equal to the trigger namespace %q", t.GetNamespace()), + Paths: []string{"namespace"}, + } + errs = errs.Also(fe) + } + if depObjRef.Kind == "" { + fe := apis.ErrMissingField("kind") + errs = errs.Also(fe) + } + if depObjRef.Name == "" { + fe := apis.ErrMissingField("name") + errs = errs.Also(fe) + } + if depObjRef.APIVersion == "" { + fe := apis.ErrMissingField("apiVersion") + errs = errs.Also(fe) + } + return errs +} + +func (t *Trigger) validateInjectionAnnotation(injectionAnnotation string) *apis.FieldError { + if injectionAnnotation != "enabled" { + return &apis.FieldError{ + Message: fmt.Sprintf(`The provided injection annotation value can only be "enabled", not %q`, injectionAnnotation), + Paths: []string{""}, + } + } + if t.Spec.Broker != "default" { + return &apis.FieldError{ + Message: fmt.Sprintf("The provided injection annotation is only used for default broker, but non-default broker specified here: %q", t.Spec.Broker), + Paths: []string{""}, + } + } + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/zz_generated.deepcopy.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..f519bfe53b --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,406 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Broker) DeepCopyInto(out *Broker) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Broker. +func (in *Broker) DeepCopy() *Broker { + if in == nil { + return nil + } + out := new(Broker) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Broker) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BrokerList) DeepCopyInto(out *BrokerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Broker, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerList. +func (in *BrokerList) DeepCopy() *BrokerList { + if in == nil { + return nil + } + out := new(BrokerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BrokerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BrokerSpec) DeepCopyInto(out *BrokerSpec) { + *out = *in + if in.ChannelTemplate != nil { + in, out := &in.ChannelTemplate, &out.ChannelTemplate + *out = new(duckv1alpha1.ChannelTemplateSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerSpec. +func (in *BrokerSpec) DeepCopy() *BrokerSpec { + if in == nil { + return nil + } + out := new(BrokerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BrokerStatus) DeepCopyInto(out *BrokerStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + in.Address.DeepCopyInto(&out.Address) + if in.TriggerChannel != nil { + in, out := &in.TriggerChannel, &out.TriggerChannel + *out = new(v1.ObjectReference) + **out = **in + } + if in.IngressChannel != nil { + in, out := &in.IngressChannel, &out.IngressChannel + *out = new(v1.ObjectReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerStatus. +func (in *BrokerStatus) DeepCopy() *BrokerStatus { + if in == nil { + return nil + } + out := new(BrokerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventType) DeepCopyInto(out *EventType) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventType. +func (in *EventType) DeepCopy() *EventType { + if in == nil { + return nil + } + out := new(EventType) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EventType) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventTypeList) DeepCopyInto(out *EventTypeList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]EventType, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventTypeList. +func (in *EventTypeList) DeepCopy() *EventTypeList { + if in == nil { + return nil + } + out := new(EventTypeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EventTypeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventTypeSpec) DeepCopyInto(out *EventTypeSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventTypeSpec. +func (in *EventTypeSpec) DeepCopy() *EventTypeSpec { + if in == nil { + return nil + } + out := new(EventTypeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventTypeStatus) DeepCopyInto(out *EventTypeStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventTypeStatus. +func (in *EventTypeStatus) DeepCopy() *EventTypeStatus { + if in == nil { + return nil + } + out := new(EventTypeStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Trigger) DeepCopyInto(out *Trigger) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Trigger. +func (in *Trigger) DeepCopy() *Trigger { + if in == nil { + return nil + } + out := new(Trigger) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Trigger) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerFilter) DeepCopyInto(out *TriggerFilter) { + *out = *in + if in.DeprecatedSourceAndType != nil { + in, out := &in.DeprecatedSourceAndType, &out.DeprecatedSourceAndType + *out = new(TriggerFilterSourceAndType) + **out = **in + } + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = new(TriggerFilterAttributes) + if **in != nil { + in, out := *in, *out + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerFilter. +func (in *TriggerFilter) DeepCopy() *TriggerFilter { + if in == nil { + return nil + } + out := new(TriggerFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in TriggerFilterAttributes) DeepCopyInto(out *TriggerFilterAttributes) { + { + in := &in + *out = make(TriggerFilterAttributes, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerFilterAttributes. +func (in TriggerFilterAttributes) DeepCopy() TriggerFilterAttributes { + if in == nil { + return nil + } + out := new(TriggerFilterAttributes) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerFilterSourceAndType) DeepCopyInto(out *TriggerFilterSourceAndType) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerFilterSourceAndType. +func (in *TriggerFilterSourceAndType) DeepCopy() *TriggerFilterSourceAndType { + if in == nil { + return nil + } + out := new(TriggerFilterSourceAndType) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerList) DeepCopyInto(out *TriggerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Trigger, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerList. +func (in *TriggerList) DeepCopy() *TriggerList { + if in == nil { + return nil + } + out := new(TriggerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TriggerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerSpec) DeepCopyInto(out *TriggerSpec) { + *out = *in + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(TriggerFilter) + (*in).DeepCopyInto(*out) + } + if in.Subscriber != nil { + in, out := &in.Subscriber, &out.Subscriber + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerSpec. +func (in *TriggerSpec) DeepCopy() *TriggerSpec { + if in == nil { + return nil + } + out := new(TriggerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TriggerStatus) DeepCopyInto(out *TriggerStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerStatus. +func (in *TriggerStatus) DeepCopy() *TriggerStatus { + if in == nil { + return nil + } + out := new(TriggerStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/register.go b/vendor/knative.dev/eventing/pkg/apis/messaging/register.go new file mode 100644 index 0000000000..8f678adcd2 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/register.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 The Knative 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 messaging + +const ( + GroupName = "messaging.knative.dev" +) diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_defaults.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_defaults.go new file mode 100644 index 0000000000..c5dac8594f --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_defaults.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" +) + +func (c *Channel) SetDefaults(ctx context.Context) { + if c != nil && c.Spec.ChannelTemplate == nil { + // The singleton may not have been set, if so ignore it and validation will reject the + // Channel. + if cd := eventingduckv1alpha1.ChannelDefaulterSingleton; cd != nil { + channelTemplate := cd.GetDefault(c.Namespace) + c.Spec.ChannelTemplate = channelTemplate + } + } + c.Spec.SetDefaults(ctx) +} + +func (cs *ChannelSpec) SetDefaults(ctx context.Context) {} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_lifecycle.go new file mode 100644 index 0000000000..1d97922ea1 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_lifecycle.go @@ -0,0 +1,94 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + eventingduck "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + "knative.dev/pkg/apis/duck/v1alpha1" +) + +var chCondSet = apis.NewLivingConditionSet(ChannelConditionBackingChannelReady, ChannelConditionAddressable) + +const ( + // ChannelConditionReady has status True when all subconditions below have been set to True. + ChannelConditionReady = apis.ConditionReady + + // ChannelConditionBackingChannelReady has status True when the backing Channel CRD is ready. + ChannelConditionBackingChannelReady apis.ConditionType = "BackingChannelReady" + + // ChannelConditionAddressable has status true when this Channel meets + // the Addressable contract and has a non-empty hostname. + ChannelConditionAddressable apis.ConditionType = "Addressable" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (cs *ChannelStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return chCondSet.Manage(cs).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (cs *ChannelStatus) IsReady() bool { + return chCondSet.Manage(cs).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (cs *ChannelStatus) InitializeConditions() { + chCondSet.Manage(cs).InitializeConditions() +} + +func (cs *ChannelStatus) SetAddress(address *v1alpha1.Addressable) { + if cs.Address == nil { + cs.Address = &v1alpha1.Addressable{} + } + if address != nil && address.URL != nil { + cs.Address.Hostname = address.URL.Host + cs.Address.URL = address.URL + chCondSet.Manage(cs).MarkTrue(ChannelConditionAddressable) + } else { + cs.Address.Hostname = "" + cs.Address.URL = nil + chCondSet.Manage(cs).MarkFalse(ChannelConditionAddressable, "EmptyHostname", "hostname is the empty string") + } +} + +func (cs *ChannelStatus) MarkBackingChannelFailed(reason, messageFormat string, messageA ...interface{}) { + chCondSet.Manage(cs).MarkFalse(ChannelConditionBackingChannelReady, reason, messageFormat, messageA...) +} + +func (cs *ChannelStatus) MarkBackingChannelReady() { + chCondSet.Manage(cs).MarkTrue(ChannelConditionBackingChannelReady) +} + +func (cs *ChannelStatus) PropagateStatuses(chs *eventingduck.ChannelableStatus) { + // TODO: Once you can get a Ready status from Channelable in a generic way, use it here. + readyCondition := chs.Status.GetCondition(apis.ConditionReady) + if readyCondition != nil { + if readyCondition.Status != corev1.ConditionTrue { + cs.MarkBackingChannelFailed(readyCondition.Reason, readyCondition.Message) + } else { + cs.MarkBackingChannelReady() + } + } + // Set the address and update the Addressable conditions. + cs.SetAddress(chs.AddressStatus.Address) + // Set the subscribable status. + if subscribableTypeStatus := chs.GetSubscribableTypeStatus(); subscribableTypeStatus != nil { + cs.SetSubscribableTypeStatus(*subscribableTypeStatus) + } +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_types.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_types.go new file mode 100644 index 0000000000..601d9dbae6 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_types.go @@ -0,0 +1,116 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + eventingduck "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/webhook" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Channel represents a generic Channel. It is normally used when we want a Channel, but don't need a specific Channel implementation. +type Channel struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the Channel. + Spec ChannelSpec `json:"spec,omitempty"` + + // Status represents the current state of the Channel. This data may be out of + // date. + // +optional + Status ChannelStatus `json:"status,omitempty"` +} + +var ( + // Check that Channel can be validated and defaulted. + _ apis.Validatable = (*Channel)(nil) + _ apis.Defaultable = (*Channel)(nil) + + // Check that Channel can return its spec untyped. + _ apis.HasSpec = (*Channel)(nil) + + _ runtime.Object = (*Channel)(nil) + _ webhook.GenericCRD = (*Channel)(nil) + + // Check that we can create OwnerReferences to a Channel. + _ kmeta.OwnerRefable = (*Channel)(nil) +) + +// ChannelSpec defines which subscribers have expressed interest in receiving events from this Channel. +// It also defines the ChannelTemplate to use in order to create the CRD Channel backing this Channel. +type ChannelSpec struct { + + // ChannelTemplate specifies which Channel CRD to use to create the CRD Channel backing this Channel. + // This is immutable after creation. Normally this is set by the Channel defaulter, not directly by the user. + ChannelTemplate *eventingduck.ChannelTemplateSpec `json:"channelTemplate"` + + // Channel conforms to Duck type Subscribable. + Subscribable *eventingduck.Subscribable `json:"subscribable,omitempty"` +} + +// ChannelStatus represents the current state of a Channel. +type ChannelStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // Channel is Addressable. It currently exposes the endpoint as a + // fully-qualified DNS name which will distribute traffic over the + // provided targets from inside the cluster. + // + // It generally has the form {channel}.{namespace}.svc.{cluster domain name} + duckv1alpha1.AddressStatus `json:",inline"` + + // Subscribers is populated with the statuses of each of the Channelable's subscribers. + eventingduck.SubscribableTypeStatus `json:",inline"` + + // Channel is an ObjectReference to the Channel CRD backing this Channel. + Channel *corev1.ObjectReference `json:"channel,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ChannelList is a collection of Channels. +type ChannelList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []Channel `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for Channels. +func (dc *Channel) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Channel") +} + +// GetUntypedSpec returns the spec of the Channel. +func (c *Channel) GetUntypedSpec() interface{} { + return c.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_validation.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_validation.go new file mode 100644 index 0000000000..401a816c53 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/channel_validation.go @@ -0,0 +1,95 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + "fmt" + + "github.com/google/go-cmp/cmp/cmpopts" + "knative.dev/pkg/kmp" + + eventingduck "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" +) + +func (c *Channel) Validate(ctx context.Context) *apis.FieldError { + return c.Spec.Validate(ctx).ViaField("spec") +} + +func (cs *ChannelSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + + if cs.ChannelTemplate == nil { + // The Channel defaulter is expected to set this, not the users. + errs = errs.Also(apis.ErrMissingField("channelTemplate")) + } else { + if cte := isValidChannelTemplate(cs.ChannelTemplate); cte != nil { + errs = errs.Also(cte.ViaField("channelTemplate")) + } + } + + if cs.Subscribable != nil { + for i, subscriber := range cs.Subscribable.Subscribers { + if subscriber.ReplyURI == "" && subscriber.SubscriberURI == "" { + fe := apis.ErrMissingField("replyURI", "subscriberURI") + fe.Details = "expected at least one of, got none" + errs = errs.Also(fe.ViaField(fmt.Sprintf("subscriber[%d]", i)).ViaField("subscribable")) + } + } + } + + return errs +} + +func isValidChannelTemplate(ct *eventingduck.ChannelTemplateSpec) *apis.FieldError { + var errs *apis.FieldError + if ct.Kind == "" { + errs = errs.Also(apis.ErrMissingField("kind")) + } + if ct.APIVersion == "" { + errs = errs.Also(apis.ErrMissingField("apiVersion")) + } + return errs +} + +func (c *Channel) CheckImmutableFields(ctx context.Context, og apis.Immutable) *apis.FieldError { + if og == nil { + return nil + } + + original, ok := og.(*Channel) + if !ok { + return &apis.FieldError{Message: "The provided original was not a Channel"} + } + + ignoreArguments := cmpopts.IgnoreFields(ChannelSpec{}, "Subscribable") + if diff, err := kmp.ShortDiff(original.Spec, c.Spec, ignoreArguments); err != nil { + return &apis.FieldError{ + Message: "Failed to diff Channel", + Paths: []string{"spec"}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec"}, + Details: diff, + } + } + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/doc.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/doc.go new file mode 100644 index 0000000000..64e1d2ec05 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 is the v1alpha1 version of the API. +// +k8s:deepcopy-gen=package +// +groupName=messaging.knative.dev +package v1alpha1 diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_defaults.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_defaults.go new file mode 100644 index 0000000000..7b51ec14cf --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_defaults.go @@ -0,0 +1,27 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import "context" + +func (imc *InMemoryChannel) SetDefaults(ctx context.Context) { + imc.Spec.SetDefaults(ctx) +} + +func (imcs *InMemoryChannelSpec) SetDefaults(ctx context.Context) { + // TODO: Nothing to default here... +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_lifecycle.go new file mode 100644 index 0000000000..15f55e20e0 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_lifecycle.go @@ -0,0 +1,125 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "knative.dev/pkg/apis" + "knative.dev/pkg/apis/duck/v1alpha1" +) + +var imcCondSet = apis.NewLivingConditionSet(InMemoryChannelConditionDispatcherReady, InMemoryChannelConditionServiceReady, InMemoryChannelConditionEndpointsReady, InMemoryChannelConditionAddressable, InMemoryChannelConditionChannelServiceReady) + +const ( + // InMemoryChannelConditionReady has status True when all subconditions below have been set to True. + InMemoryChannelConditionReady = apis.ConditionReady + + // InMemoryChannelConditionDispatcherReady has status True when a Dispatcher deployment is ready + // Keyed off appsv1.DeploymentAvaialble, which means minimum available replicas required are up + // and running for at least minReadySeconds. + InMemoryChannelConditionDispatcherReady apis.ConditionType = "DispatcherReady" + + // InMemoryChannelConditionServiceReady has status True when a k8s Service is ready. This + // basically just means it exists because there's no meaningful status in Service. See Endpoints + // below. + InMemoryChannelConditionServiceReady apis.ConditionType = "ServiceReady" + + // InMemoryChannelConditionEndpointsReady has status True when a k8s Service Endpoints are backed + // by at least one endpoint. + InMemoryChannelConditionEndpointsReady apis.ConditionType = "EndpointsReady" + + // InMemoryChannelConditionAddressable has status true when this InMemoryChannel meets + // the Addressable contract and has a non-empty hostname. + InMemoryChannelConditionAddressable apis.ConditionType = "Addressable" + + // InMemoryChannelConditionServiceReady has status True when a k8s Service representing the channel is ready. + // Because this uses ExternalName, there are no endpoints to check. + InMemoryChannelConditionChannelServiceReady apis.ConditionType = "ChannelServiceReady" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (imcs *InMemoryChannelStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return imcCondSet.Manage(imcs).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (imcs *InMemoryChannelStatus) IsReady() bool { + return imcCondSet.Manage(imcs).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (imcs *InMemoryChannelStatus) InitializeConditions() { + imcCondSet.Manage(imcs).InitializeConditions() +} + +// TODO: Use the new beta duck types. +func (imcs *InMemoryChannelStatus) SetAddress(url *apis.URL) { + if imcs.Address == nil { + imcs.Address = &v1alpha1.Addressable{} + } + if url != nil { + imcs.Address.Hostname = url.Host + imcs.Address.URL = url + imcCondSet.Manage(imcs).MarkTrue(InMemoryChannelConditionAddressable) + } else { + imcs.Address.Hostname = "" + imcs.Address.URL = nil + imcCondSet.Manage(imcs).MarkFalse(InMemoryChannelConditionAddressable, "emptyHostname", "hostname is the empty string") + } +} + +func (imcs *InMemoryChannelStatus) MarkDispatcherFailed(reason, messageFormat string, messageA ...interface{}) { + imcCondSet.Manage(imcs).MarkFalse(InMemoryChannelConditionDispatcherReady, reason, messageFormat, messageA...) +} + +// TODO: Unify this with the ones from Eventing. Say: Broker, Trigger. +func (imcs *InMemoryChannelStatus) PropagateDispatcherStatus(ds *appsv1.DeploymentStatus) { + for _, cond := range ds.Conditions { + if cond.Type == appsv1.DeploymentAvailable { + if cond.Status != corev1.ConditionTrue { + imcs.MarkDispatcherFailed("DispatcherNotReady", "Dispatcher Deployment is not ready: %s : %s", cond.Reason, cond.Message) + } else { + imcCondSet.Manage(imcs).MarkTrue(InMemoryChannelConditionDispatcherReady) + } + } + } +} + +func (imcs *InMemoryChannelStatus) MarkServiceFailed(reason, messageFormat string, messageA ...interface{}) { + imcCondSet.Manage(imcs).MarkFalse(InMemoryChannelConditionServiceReady, reason, messageFormat, messageA...) +} + +func (imcs *InMemoryChannelStatus) MarkServiceTrue() { + imcCondSet.Manage(imcs).MarkTrue(InMemoryChannelConditionServiceReady) +} + +func (imcs *InMemoryChannelStatus) MarkChannelServiceFailed(reason, messageFormat string, messageA ...interface{}) { + imcCondSet.Manage(imcs).MarkFalse(InMemoryChannelConditionChannelServiceReady, reason, messageFormat, messageA...) +} + +func (imcs *InMemoryChannelStatus) MarkChannelServiceTrue() { + imcCondSet.Manage(imcs).MarkTrue(InMemoryChannelConditionChannelServiceReady) +} + +func (imcs *InMemoryChannelStatus) MarkEndpointsFailed(reason, messageFormat string, messageA ...interface{}) { + imcCondSet.Manage(imcs).MarkFalse(InMemoryChannelConditionEndpointsReady, reason, messageFormat, messageA...) +} + +func (imcs *InMemoryChannelStatus) MarkEndpointsTrue() { + imcCondSet.Manage(imcs).MarkTrue(InMemoryChannelConditionEndpointsReady) +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_types.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_types.go new file mode 100644 index 0000000000..163b7b4bcb --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_types.go @@ -0,0 +1,108 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + eventingduck "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/webhook" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// InMemoryChannel is a resource representing an in memory channel +type InMemoryChannel struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the Channel. + Spec InMemoryChannelSpec `json:"spec,omitempty"` + + // Status represents the current state of the Channel. This data may be out of + // date. + // +optional + Status InMemoryChannelStatus `json:"status,omitempty"` +} + +var ( + // Check that InMemoryChannel can be validated and defaulted. + _ apis.Validatable = (*InMemoryChannel)(nil) + _ apis.Defaultable = (*InMemoryChannel)(nil) + + // Check that InMemoryChannel can return its spec untyped. + _ apis.HasSpec = (*InMemoryChannel)(nil) + + _ runtime.Object = (*InMemoryChannel)(nil) + _ webhook.GenericCRD = (*InMemoryChannel)(nil) + + // Check that we can create OwnerReferences to an InMemoryChannel. + _ kmeta.OwnerRefable = (*InMemoryChannel)(nil) +) + +// InMemoryChannelSpec defines which subscribers have expressed interest in +// receiving events from this InMemoryChannel. +// arguments for a Channel. +type InMemoryChannelSpec struct { + // Channel conforms to Duck type Subscribable. + Subscribable *eventingduck.Subscribable `json:"subscribable,omitempty"` +} + +// ChannelStatus represents the current state of a Channel. +type InMemoryChannelStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // InMemoryChannel is Addressable. It currently exposes the endpoint as a + // fully-qualified DNS name which will distribute traffic over the + // provided targets from inside the cluster. + // + // It generally has the form {channel}.{namespace}.svc.{cluster domain name} + duckv1alpha1.AddressStatus `json:",inline"` + + // Subscribers is populated with the statuses of each of the Channelable's subscribers. + eventingduck.SubscribableTypeStatus `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// InMemoryChannelList is a collection of in-memory channels. +type InMemoryChannelList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []InMemoryChannel `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for InMemoryChannels +func (imc *InMemoryChannel) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("InMemoryChannel") +} + +// GetUntypedSpec returns the spec of the InMemoryChannel. +func (i *InMemoryChannel) GetUntypedSpec() interface{} { + return i.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_validation.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_validation.go new file mode 100644 index 0000000000..f330b2661f --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/in_memory_channel_validation.go @@ -0,0 +1,44 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + "fmt" + + "knative.dev/pkg/apis" +) + +func (imc *InMemoryChannel) Validate(ctx context.Context) *apis.FieldError { + return imc.Spec.Validate(ctx).ViaField("spec") +} + +func (imcs *InMemoryChannelSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + + if imcs.Subscribable != nil { + for i, subscriber := range imcs.Subscribable.Subscribers { + if subscriber.ReplyURI == "" && subscriber.SubscriberURI == "" { + fe := apis.ErrMissingField("replyURI", "subscriberURI") + fe.Details = "expected at least one of, got none" + errs = errs.Also(fe.ViaField(fmt.Sprintf("subscriber[%d]", i)).ViaField("subscribable")) + } + } + } + + return errs +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_defaults.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_defaults.go new file mode 100644 index 0000000000..21461dff7c --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_defaults.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" +) + +func (s *Parallel) SetDefaults(ctx context.Context) { + if s != nil && s.Spec.ChannelTemplate == nil { + // The singleton may not have been set, if so ignore it and validation will reject the + // Channel. + if cd := eventingduckv1alpha1.ChannelDefaulterSingleton; cd != nil { + channelTemplate := cd.GetDefault(s.Namespace) + s.Spec.ChannelTemplate = channelTemplate + } + } + s.Spec.SetDefaults(ctx) +} + +func (ss *ParallelSpec) SetDefaults(ctx context.Context) {} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_lifecycle.go new file mode 100644 index 0000000000..9445e3fd2d --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_lifecycle.go @@ -0,0 +1,237 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + pkgduckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" +) + +var pParallelCondSet = apis.NewLivingConditionSet(ParallelConditionReady, ParallelConditionChannelsReady, ParallelConditionSubscriptionsReady, ParallelConditionAddressable) + +const ( + // StatusConditionTypeDeprecated is the status.conditions.type used to provide deprecation + // warnings. + StatusConditionTypeDeprecated = "Deprecated" +) + +const ( + // ParallelConditionReady has status True when all subconditions below have been set to True. + ParallelConditionReady = apis.ConditionReady + + // ParallelConditionChannelsReady has status True when all the channels created as part of + // this parallel are ready. + ParallelConditionChannelsReady apis.ConditionType = "ChannelsReady" + + // ParallelConditionSubscriptionsReady has status True when all the subscriptions created as part of + // this parallel are ready. + ParallelConditionSubscriptionsReady apis.ConditionType = "SubscriptionsReady" + + // ParallelConditionAddressable has status true when this Parallel meets + // the Addressable contract and has a non-empty hostname. + ParallelConditionAddressable apis.ConditionType = "Addressable" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (ps *ParallelStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return pParallelCondSet.Manage(ps).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (ps *ParallelStatus) IsReady() bool { + return pParallelCondSet.Manage(ps).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (ps *ParallelStatus) InitializeConditions() { + pParallelCondSet.Manage(ps).InitializeConditions() +} + +// PropagateSubscriptionStatuses sets the ParallelConditionSubscriptionsReady based on +// the status of the incoming subscriptions. +func (ps *ParallelStatus) PropagateSubscriptionStatuses(filterSubscriptions []*Subscription, subscriptions []*Subscription) { + if ps.BranchStatuses == nil { + ps.BranchStatuses = make([]ParallelBranchStatus, len(subscriptions)) + } + allReady := true + // If there are no subscriptions, treat that as a False branch. Could go either way, but this seems right. + if len(subscriptions) == 0 { + allReady = false + } + + for i, s := range subscriptions { + ps.BranchStatuses[i].SubscriptionStatus = ParallelSubscriptionStatus{ + Subscription: corev1.ObjectReference{ + APIVersion: s.APIVersion, + Kind: s.Kind, + Name: s.Name, + Namespace: s.Namespace, + }, + } + + readyCondition := s.Status.GetCondition(SubscriptionConditionReady) + if readyCondition != nil { + ps.BranchStatuses[i].SubscriptionStatus.ReadyCondition = *readyCondition + if readyCondition.Status != corev1.ConditionTrue { + allReady = false + } + } else { + allReady = false + } + + fs := filterSubscriptions[i] + ps.BranchStatuses[i].FilterSubscriptionStatus = ParallelSubscriptionStatus{ + Subscription: corev1.ObjectReference{ + APIVersion: fs.APIVersion, + Kind: fs.Kind, + Name: fs.Name, + Namespace: fs.Namespace, + }, + } + readyCondition = fs.Status.GetCondition(SubscriptionConditionReady) + if readyCondition != nil { + ps.BranchStatuses[i].FilterSubscriptionStatus.ReadyCondition = *readyCondition + if readyCondition.Status != corev1.ConditionTrue { + allReady = false + } + } else { + allReady = false + } + + } + if allReady { + pParallelCondSet.Manage(ps).MarkTrue(ParallelConditionSubscriptionsReady) + } else { + ps.MarkSubscriptionsNotReady("SubscriptionsNotReady", "Subscriptions are not ready yet, or there are none") + } +} + +// PropagateChannelStatuses sets the ChannelStatuses and ParallelConditionChannelsReady based on the +// status of the incoming channels. +func (ps *ParallelStatus) PropagateChannelStatuses(ingressChannel *duckv1alpha1.Channelable, channels []*duckv1alpha1.Channelable) { + if ps.BranchStatuses == nil { + ps.BranchStatuses = make([]ParallelBranchStatus, len(channels)) + } + allReady := true + + ps.IngressChannelStatus.Channel = corev1.ObjectReference{ + APIVersion: ingressChannel.APIVersion, + Kind: ingressChannel.Kind, + Name: ingressChannel.Name, + Namespace: ingressChannel.Namespace, + } + + address := ingressChannel.Status.AddressStatus.Address + if address != nil { + ps.IngressChannelStatus.ReadyCondition = apis.Condition{Type: apis.ConditionReady, Status: corev1.ConditionTrue} + } else { + ps.IngressChannelStatus.ReadyCondition = apis.Condition{Type: apis.ConditionReady, Status: corev1.ConditionFalse, Reason: "NotAddressable", Message: "Channel is not addressable"} + allReady = false + } + // Propagate ingress channel address to Parallel + ps.setAddress(address) + + for i, c := range channels { + ps.BranchStatuses[i].FilterChannelStatus = ParallelChannelStatus{ + Channel: corev1.ObjectReference{ + APIVersion: c.APIVersion, + Kind: c.Kind, + Name: c.Name, + Namespace: c.Namespace, + }, + } + // TODO: Once the addressable has a real status to dig through, use that here instead of + // addressable, because it might be addressable but not ready. + address := c.Status.AddressStatus.Address + if address != nil { + ps.BranchStatuses[i].FilterChannelStatus.ReadyCondition = apis.Condition{Type: apis.ConditionReady, Status: corev1.ConditionTrue} + } else { + ps.BranchStatuses[i].FilterChannelStatus.ReadyCondition = apis.Condition{Type: apis.ConditionReady, Status: corev1.ConditionFalse, Reason: "NotAddressable", Message: "Channel is not addressable"} + allReady = false + } + } + if allReady { + pParallelCondSet.Manage(ps).MarkTrue(ParallelConditionChannelsReady) + } else { + ps.MarkChannelsNotReady("ChannelsNotReady", "Channels are not ready yet, or there are none") + } +} + +func (ps *ParallelStatus) MarkChannelsNotReady(reason, messageFormat string, messageA ...interface{}) { + pParallelCondSet.Manage(ps).MarkFalse(ParallelConditionChannelsReady, reason, messageFormat, messageA...) +} + +func (ps *ParallelStatus) MarkSubscriptionsNotReady(reason, messageFormat string, messageA ...interface{}) { + pParallelCondSet.Manage(ps).MarkFalse(ParallelConditionSubscriptionsReady, reason, messageFormat, messageA...) +} + +func (ps *ParallelStatus) MarkAddressableNotReady(reason, messageFormat string, messageA ...interface{}) { + pParallelCondSet.Manage(ps).MarkFalse(ParallelConditionAddressable, reason, messageFormat, messageA...) +} + +func (ps *ParallelStatus) setAddress(address *pkgduckv1alpha1.Addressable) { + ps.Address = address + + if address == nil { + pParallelCondSet.Manage(ps).MarkFalse(ParallelConditionAddressable, "emptyHostname", "hostname is the empty string") + return + } + if address.URL != nil || address.Hostname != "" { + pParallelCondSet.Manage(ps).MarkTrue(ParallelConditionAddressable) + } else { + ps.Address.Hostname = "" + ps.Address.URL = nil + pParallelCondSet.Manage(ps).MarkFalse(ParallelConditionAddressable, "emptyHostname", "hostname is the empty string") + } +} + +// MarkDeprecated adds a warning condition that this object's spec is using deprecated fields +// and will stop working in the future. Note that this does not affect the Ready condition. +func (ps *ParallelStatus) MarkDestinationDeprecatedRef(reason, msg string) { + dc := apis.Condition{ + Type: StatusConditionTypeDeprecated, + Reason: reason, + Status: corev1.ConditionTrue, + Severity: apis.ConditionSeverityWarning, + Message: msg, + LastTransitionTime: apis.VolatileTime{Inner: metav1.NewTime(time.Now())}, + } + for i, c := range ps.Conditions { + if c.Type == dc.Type { + ps.Conditions[i] = dc + return + } + } + ps.Conditions = append(ps.Conditions, dc) +} + +// ClearDeprecated removes the StatusConditionTypeDeprecated warning condition. Note that this does not +// affect the Ready condition. +func (ps *ParallelStatus) ClearDeprecated() { + conds := make([]apis.Condition, 0, len(ps.Conditions)) + for _, c := range ps.Conditions { + if c.Type != StatusConditionTypeDeprecated { + conds = append(conds, c) + } + } + ps.Conditions = conds +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_types.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_types.go new file mode 100644 index 0000000000..be655258bf --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_types.go @@ -0,0 +1,163 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis/v1alpha1" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/webhook" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// Parallel defines conditional branches that will be wired in +// series through Channels and Subscriptions. +type Parallel struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the Parallel. + Spec ParallelSpec `json:"spec,omitempty"` + + // Status represents the current state of the Parallel. This data may be out of + // date. + // +optional + Status ParallelStatus `json:"status,omitempty"` +} + +var ( + // Check that Parallel can be validated and defaulted. + _ apis.Validatable = (*Parallel)(nil) + _ apis.Defaultable = (*Parallel)(nil) + + // Check that Parallel can return its spec untyped. + _ apis.HasSpec = (*Parallel)(nil) + + // TODO: make appropriate fields immutable. + //_ apis.Immutable = (*Parallel)(nil) + + _ runtime.Object = (*Parallel)(nil) + _ webhook.GenericCRD = (*Parallel)(nil) + + // Check that we can create OwnerReferences to a Parallel. + _ kmeta.OwnerRefable = (*Parallel)(nil) +) + +type ParallelSpec struct { + // Branches is the list of Filter/Subscribers pairs. + Branches []ParallelBranch `json:"branches"` + + // ChannelTemplate specifies which Channel CRD to use. If left unspecified, it is set to the default Channel CRD + // for the namespace (or cluster, in case there are no defaults for the namespace). + // +optional + ChannelTemplate *eventingduckv1alpha1.ChannelTemplateSpec `json:"channelTemplate"` + + // Reply is a Reference to where the result of a case Subscriber gets sent to + // when the case does not have a Reply + // +optional + Reply *v1alpha1.Destination `json:"reply,omitempty"` +} + +type ParallelBranch struct { + // Filter is the expression guarding the branch + Filter *v1alpha1.Destination `json:"filter,omitempty"` + + // Subscriber receiving the event when the filter passes + Subscriber v1alpha1.Destination `json:"subscriber"` + + // Reply is a Reference to where the result of Subscriber of this case gets sent to. + // If not specified, sent the result to the Parallel Reply + // +optional + Reply *v1alpha1.Destination `json:"reply,omitempty"` +} + +// ParallelStatus represents the current state of a Parallel. +type ParallelStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // IngressChannelStatus corresponds to the ingress channel status. + IngressChannelStatus ParallelChannelStatus `json:"ingressChannelStatus"` + + // BranchStatuses is an array of corresponding to branch statuses. + // Matches the Spec.Branches array in the order. + BranchStatuses []ParallelBranchStatus `json:"branchStatuses"` + + // AddressStatus is the starting point to this Parallel. Sending to this + // will target the first subscriber. + // It generally has the form {channel}.{namespace}.svc.{cluster domain name} + duckv1alpha1.AddressStatus `json:",inline"` +} + +// ParallelBranchStatus represents the current state of a Parallel branch +type ParallelBranchStatus struct { + // FilterSubscriptionStatus corresponds to the filter subscription status. + FilterSubscriptionStatus ParallelSubscriptionStatus `json:"filterSubscriptionStatus"` + + // FilterChannelStatus corresponds to the filter channel status. + FilterChannelStatus ParallelChannelStatus `json:"filterChannelStatus"` + + // SubscriptionStatus corresponds to the subscriber subscription status. + SubscriptionStatus ParallelSubscriptionStatus `json:"subscriberSubscriptionStatus"` +} + +type ParallelChannelStatus struct { + // Channel is the reference to the underlying channel. + Channel corev1.ObjectReference `json:"channel"` + + // ReadyCondition indicates whether the Channel is ready or not. + ReadyCondition apis.Condition `json:"ready"` +} + +type ParallelSubscriptionStatus struct { + // Subscription is the reference to the underlying Subscription. + Subscription corev1.ObjectReference `json:"subscription"` + + // ReadyCondition indicates whether the Subscription is ready or not. + ReadyCondition apis.Condition `json:"ready"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ParallelList is a collection of Parallels. +type ParallelList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []Parallel `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for Parallel +func (p *Parallel) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Parallel") +} + +// GetUntypedSpec returns the spec of the Parallel. +func (p *Parallel) GetUntypedSpec() interface{} { + return p.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_validation.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_validation.go new file mode 100644 index 0000000000..ba6ae1f290 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/parallel_validation.go @@ -0,0 +1,68 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + "knative.dev/pkg/apis" +) + +func (p *Parallel) Validate(ctx context.Context) *apis.FieldError { + return p.Spec.Validate(ctx).ViaField("spec") +} + +func (ps *ParallelSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + + if len(ps.Branches) == 0 { + errs = errs.Also(apis.ErrMissingField("branches")) + } + + for i, s := range ps.Branches { + if err := s.Filter.ValidateDisallowDeprecated(ctx); err != nil { + errs = errs.Also(apis.ErrInvalidArrayValue(s, "branches.filter", i)) + } + + if e := s.Subscriber.ValidateDisallowDeprecated(ctx); e != nil { + errs = errs.Also(apis.ErrInvalidArrayValue(s, "branches.subscriber", i)) + } + + if e := s.Reply.Validate(ctx); e != nil { + errs = errs.Also(apis.ErrInvalidArrayValue(s, "branches.reply", i)) + } + } + + if ps.ChannelTemplate == nil { + errs = errs.Also(apis.ErrMissingField("channelTemplate")) + return errs + } + + if len(ps.ChannelTemplate.APIVersion) == 0 { + errs = errs.Also(apis.ErrMissingField("channelTemplate.apiVersion")) + } + + if len(ps.ChannelTemplate.Kind) == 0 { + errs = errs.Also(apis.ErrMissingField("channelTemplate.kind")) + } + + if err := ps.Reply.Validate(ctx); err != nil { + errs = errs.Also(err.ViaField("reply")) + } + + return errs +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/register.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/register.go new file mode 100644 index 0000000000..db9a880c44 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/register.go @@ -0,0 +1,61 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "knative.dev/eventing/pkg/apis/messaging" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: messaging.GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &InMemoryChannel{}, + &InMemoryChannelList{}, + &Sequence{}, + &SequenceList{}, + &Subscription{}, + &SubscriptionList{}, + &Channel{}, + &ChannelList{}, + &Parallel{}, + &ParallelList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_defaults.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_defaults.go new file mode 100644 index 0000000000..017268237e --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_defaults.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" +) + +func (s *Sequence) SetDefaults(ctx context.Context) { + if s != nil && s.Spec.ChannelTemplate == nil { + // The singleton may not have been set, if so ignore it and validation will reject the + // Channel. + if cd := eventingduckv1alpha1.ChannelDefaulterSingleton; cd != nil { + channelTemplate := cd.GetDefault(s.Namespace) + s.Spec.ChannelTemplate = channelTemplate + } + } + s.Spec.SetDefaults(ctx) +} + +func (ss *SequenceSpec) SetDefaults(ctx context.Context) {} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_lifecycle.go new file mode 100644 index 0000000000..f888ec6c26 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_lifecycle.go @@ -0,0 +1,199 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + pkgduckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" +) + +var pCondSet = apis.NewLivingConditionSet(SequenceConditionReady, SequenceConditionChannelsReady, SequenceConditionSubscriptionsReady, SequenceConditionAddressable) + +const ( + // SequenceConditionReady has status True when all subconditions below have been set to True. + SequenceConditionReady = apis.ConditionReady + + // SequenceChannelsReady has status True when all the channels created as part of + // this sequence are ready. + SequenceConditionChannelsReady apis.ConditionType = "ChannelsReady" + + // SequenceSubscriptionsReady has status True when all the subscriptions created as part of + // this sequence are ready. + SequenceConditionSubscriptionsReady apis.ConditionType = "SubscriptionsReady" + + // SequenceConditionAddressable has status true when this Sequence meets + // the Addressable contract and has a non-empty hostname. + SequenceConditionAddressable apis.ConditionType = "Addressable" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (ss *SequenceStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return pCondSet.Manage(ss).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (ss *SequenceStatus) IsReady() bool { + return pCondSet.Manage(ss).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (ss *SequenceStatus) InitializeConditions() { + pCondSet.Manage(ss).InitializeConditions() +} + +// PropagateSubscriptionStatuses sets the SubscriptionStatuses and SequenceConditionSubscriptionsReady based on +// the status of the incoming subscriptions. +func (ss *SequenceStatus) PropagateSubscriptionStatuses(subscriptions []*Subscription) { + ss.SubscriptionStatuses = make([]SequenceSubscriptionStatus, len(subscriptions)) + allReady := true + // If there are no subscriptions, treat that as a False case. Could go either way, but this seems right. + if len(subscriptions) == 0 { + allReady = false + + } + for i, s := range subscriptions { + ss.SubscriptionStatuses[i] = SequenceSubscriptionStatus{ + Subscription: corev1.ObjectReference{ + APIVersion: s.APIVersion, + Kind: s.Kind, + Name: s.Name, + Namespace: s.Namespace, + }, + } + readyCondition := s.Status.GetCondition(SubscriptionConditionReady) + if readyCondition != nil { + ss.SubscriptionStatuses[i].ReadyCondition = *readyCondition + if readyCondition.Status != corev1.ConditionTrue { + allReady = false + } + } else { + allReady = false + } + + } + if allReady { + pCondSet.Manage(ss).MarkTrue(SequenceConditionSubscriptionsReady) + } else { + ss.MarkSubscriptionsNotReady("SubscriptionsNotReady", "Subscriptions are not ready yet, or there are none") + } +} + +// PropagateChannelStatuses sets the ChannelStatuses and SequenceConditionChannelsReady based on the +// status of the incoming channels. +func (ss *SequenceStatus) PropagateChannelStatuses(channels []*duckv1alpha1.Channelable) { + ss.ChannelStatuses = make([]SequenceChannelStatus, len(channels)) + allReady := true + // If there are no channels, treat that as a False case. Could go either way, but this seems right. + if len(channels) == 0 { + allReady = false + + } + for i, c := range channels { + ss.ChannelStatuses[i] = SequenceChannelStatus{ + Channel: corev1.ObjectReference{ + APIVersion: c.APIVersion, + Kind: c.Kind, + Name: c.Name, + Namespace: c.Namespace, + }, + } + // TODO: Once the addressable has a real status to dig through, use that here instead of + // addressable, because it might be addressable but not ready. + address := c.Status.AddressStatus.Address + if address != nil { + ss.ChannelStatuses[i].ReadyCondition = apis.Condition{Type: apis.ConditionReady, Status: corev1.ConditionTrue} + } else { + ss.ChannelStatuses[i].ReadyCondition = apis.Condition{Type: apis.ConditionReady, Status: corev1.ConditionFalse, Reason: "NotAddressable", Message: "Channel is not addressable"} + allReady = false + } + + // Mark the Sequence address as the Address of the first channel. + if i == 0 { + ss.setAddress(address) + } + } + if allReady { + pCondSet.Manage(ss).MarkTrue(SequenceConditionChannelsReady) + } else { + ss.MarkChannelsNotReady("ChannelsNotReady", "Channels are not ready yet, or there are none") + } +} + +func (ss *SequenceStatus) MarkChannelsNotReady(reason, messageFormat string, messageA ...interface{}) { + pCondSet.Manage(ss).MarkFalse(SequenceConditionChannelsReady, reason, messageFormat, messageA...) +} + +func (ss *SequenceStatus) MarkSubscriptionsNotReady(reason, messageFormat string, messageA ...interface{}) { + pCondSet.Manage(ss).MarkFalse(SequenceConditionSubscriptionsReady, reason, messageFormat, messageA...) +} + +func (ss *SequenceStatus) MarkAddressableNotReady(reason, messageFormat string, messageA ...interface{}) { + pCondSet.Manage(ss).MarkFalse(SequenceConditionAddressable, reason, messageFormat, messageA...) +} + +func (ss *SequenceStatus) setAddress(address *pkgduckv1alpha1.Addressable) { + ss.Address = address + + if address == nil { + pCondSet.Manage(ss).MarkFalse(SequenceConditionAddressable, "emptyHostname", "hostname is the empty string") + return + } + if address.URL != nil || address.Hostname != "" { + pCondSet.Manage(ss).MarkTrue(SequenceConditionAddressable) + } else { + ss.Address.Hostname = "" + ss.Address.URL = nil + pCondSet.Manage(ss).MarkFalse(SequenceConditionAddressable, "emptyHostname", "hostname is the empty string") + } +} + +// MarkDeprecated adds a warning condition that this object's spec is using deprecated fields +// and will stop working in the future. Note that this does not affect the Ready condition. +func (ss *SequenceStatus) MarkDestinationDeprecatedRef(reason, msg string) { + dc := apis.Condition{ + Type: StatusConditionTypeDeprecated, + Reason: reason, + Status: corev1.ConditionTrue, + Severity: apis.ConditionSeverityWarning, + Message: msg, + LastTransitionTime: apis.VolatileTime{Inner: metav1.NewTime(time.Now())}, + } + for i, c := range ss.Conditions { + if c.Type == dc.Type { + ss.Conditions[i] = dc + return + } + } + ss.Conditions = append(ss.Conditions, dc) +} + +// ClearDeprecated removes the StatusConditionTypeDeprecated warning condition. Note that this does not +// affect the Ready condition. +func (ss *SequenceStatus) ClearDeprecated() { + conds := make([]apis.Condition, 0, len(ss.Conditions)) + for _, c := range ss.Conditions { + if c.Type != StatusConditionTypeDeprecated { + conds = append(conds, c) + } + } + ss.Conditions = conds +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_types.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_types.go new file mode 100644 index 0000000000..6f59abe2ca --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_types.go @@ -0,0 +1,139 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + "knative.dev/pkg/apis/v1alpha1" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/webhook" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// Sequence defines a sequence of Subscribers that will be wired in +// series through Channels and Subscriptions. +type Sequence struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the Sequence. + Spec SequenceSpec `json:"spec,omitempty"` + + // Status represents the current state of the Sequence. This data may be out of + // date. + // +optional + Status SequenceStatus `json:"status,omitempty"` +} + +var ( + // Check that Sequence can be validated and defaulted. + _ apis.Validatable = (*Sequence)(nil) + _ apis.Defaultable = (*Sequence)(nil) + + // Check that Sequence can return its spec untyped. + _ apis.HasSpec = (*Sequence)(nil) + + // TODO: make appropriate fields immutable. + //_ apis.Immutable = (*Sequence)(nil) + + _ runtime.Object = (*Sequence)(nil) + _ webhook.GenericCRD = (*Sequence)(nil) + + // Check that we can create OwnerReferences to a Sequence. + _ kmeta.OwnerRefable = (*Sequence)(nil) +) + +type SequenceSpec struct { + // Steps is the list of Destinations (processors / functions) that will be called in the order + // provided. + Steps []v1alpha1.Destination `json:"steps"` + + // ChannelTemplate specifies which Channel CRD to use. If left unspecified, it is set to the default Channel CRD + // for the namespace (or cluster, in case there are no defaults for the namespace). + // +optional + ChannelTemplate *eventingduckv1alpha1.ChannelTemplateSpec `json:"channelTemplate,omitempty"` + + // Reply is a Reference to where the result of the last Subscriber gets sent to. + // +optional + Reply *v1alpha1.Destination `json:"reply,omitempty"` +} + +type SequenceChannelStatus struct { + // Channel is the reference to the underlying channel. + Channel corev1.ObjectReference `json:"channel"` + + // ReadyCondition indicates whether the Channel is ready or not. + ReadyCondition apis.Condition `json:"ready"` +} + +type SequenceSubscriptionStatus struct { + // Subscription is the reference to the underlying Subscription. + Subscription corev1.ObjectReference `json:"subscription"` + + // ReadyCondition indicates whether the Subscription is ready or not. + ReadyCondition apis.Condition `json:"ready"` +} + +// SequenceStatus represents the current state of a Sequence. +type SequenceStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // SubscriptionStatuses is an array of corresponding Subscription statuses. + // Matches the Spec.Steps array in the order. + SubscriptionStatuses []SequenceSubscriptionStatus `json:"subscriptionStatuses"` + + // ChannelStatuses is an array of corresponding Channel statuses. + // Matches the Spec.Steps array in the order. + ChannelStatuses []SequenceChannelStatus `json:"channelStatuses"` + + // AddressStatus is the starting point to this Sequence. Sending to this + // will target the first subscriber. + // It generally has the form {channel}.{namespace}.svc.{cluster domain name} + duckv1alpha1.AddressStatus `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SequenceList is a collection of Sequences. +type SequenceList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []Sequence `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for InMemoryChannels +func (p *Sequence) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Sequence") +} + +// GetUntypedSpec returns the spec of the Sequence. +func (s *Sequence) GetUntypedSpec() interface{} { + return s.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_validation.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_validation.go new file mode 100644 index 0000000000..c7c388cf35 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/sequence_validation.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + "knative.dev/pkg/apis" +) + +func (p *Sequence) Validate(ctx context.Context) *apis.FieldError { + return p.Spec.Validate(ctx).ViaField("spec") +} + +func (ps *SequenceSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + + if len(ps.Steps) == 0 { + errs = errs.Also(apis.ErrMissingField("steps")) + } + + for i, s := range ps.Steps { + if e := s.ValidateDisallowDeprecated(ctx); e != nil { + errs = errs.Also(apis.ErrInvalidArrayValue(s, "steps", i)) + } + } + + if ps.ChannelTemplate == nil { + errs = errs.Also(apis.ErrMissingField("channelTemplate")) + return errs + } + + if len(ps.ChannelTemplate.APIVersion) == 0 { + errs = errs.Also(apis.ErrMissingField("channelTemplate.apiVersion")) + } + + if len(ps.ChannelTemplate.Kind) == 0 { + errs = errs.Also(apis.ErrMissingField("channelTemplate.kind")) + } + + if err := ps.Reply.Validate(ctx); err != nil { + errs = errs.Also(err.ViaField("reply")) + } + + return errs +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscribable_channelable_validation.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscribable_channelable_validation.go new file mode 100644 index 0000000000..87dc0b05df --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscribable_channelable_validation.go @@ -0,0 +1,85 @@ +/* +Copyright 2018 The Knative 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 v1alpha1 + +import ( + "reflect" + + "github.com/google/go-cmp/cmp" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + "knative.dev/pkg/apis" +) + +func isChannelEmpty(f corev1.ObjectReference) bool { + return equality.Semantic.DeepEqual(f, corev1.ObjectReference{}) +} + +// Valid if it is a valid object reference. +func isValidChannel(f corev1.ObjectReference) *apis.FieldError { + return IsValidObjectReference(f) +} + +func IsValidObjectReference(f corev1.ObjectReference) *apis.FieldError { + return checkRequiredObjectReferenceFields(f). + Also(checkDisallowedObjectReferenceFields(f)) +} + +// Check the corev1.ObjectReference to make sure it has the required fields. They +// are not checked for anything more except that they are set. +func checkRequiredObjectReferenceFields(f corev1.ObjectReference) *apis.FieldError { + var errs *apis.FieldError + if f.Name == "" { + errs = errs.Also(apis.ErrMissingField("name")) + } + if f.APIVersion == "" { + errs = errs.Also(apis.ErrMissingField("apiVersion")) + } + if f.Kind == "" { + errs = errs.Also(apis.ErrMissingField("kind")) + } + return errs +} + +// Check the corev1.ObjectReference to make sure it only has the following fields set: +// Name, Kind, APIVersion +// If any other fields are set and is not the Zero value, returns an apis.FieldError +// with the fieldpaths for all those fields. +func checkDisallowedObjectReferenceFields(f corev1.ObjectReference) *apis.FieldError { + disallowedFields := []string{} + // See if there are any fields that have been set that should not be. + // TODO: Hoist this kind of stuff into pkg repository. + s := reflect.ValueOf(f) + typeOf := s.Type() + for i := 0; i < s.NumField(); i++ { + field := s.Field(i) + fieldName := typeOf.Field(i).Name + if fieldName == "Name" || fieldName == "Kind" || fieldName == "APIVersion" { + continue + } + if !cmp.Equal(field.Interface(), reflect.Zero(field.Type()).Interface()) { + disallowedFields = append(disallowedFields, fieldName) + } + } + if len(disallowedFields) > 0 { + fe := apis.ErrDisallowedFields(disallowedFields...) + fe.Details = "only name, apiVersion and kind are supported fields" + return fe + } + return nil + +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_defaults.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_defaults.go new file mode 100644 index 0000000000..9b64991284 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_defaults.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 The Knative 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 v1alpha1 + +import ( + "context" +) + +func (s *Subscription) SetDefaults(ctx context.Context) { + s.Spec.SetDefaults(ctx) +} + +func (ss *SubscriptionSpec) SetDefaults(ctx context.Context) { + // TODO anything? +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_lifecycle.go new file mode 100644 index 0000000000..f5a3965f14 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_lifecycle.go @@ -0,0 +1,131 @@ +/* + * Copyright 2019 The Knative 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 v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + + "knative.dev/pkg/apis" +) + +// subCondSet is a condition set with Ready as the happy condition and +// ReferencesResolved and ChannelReady as the dependent conditions. +var subCondSet = apis.NewLivingConditionSet(SubscriptionConditionReferencesResolved, SubscriptionConditionAddedToChannel, SubscriptionConditionChannelReady) + +const ( + // SubscriptionConditionReady has status True when all subconditions below have been set to True. + SubscriptionConditionReady = apis.ConditionReady + // SubscriptionConditionReferencesResolved has status True when all the specified references have been successfully + // resolved. + SubscriptionConditionReferencesResolved apis.ConditionType = "Resolved" + + // SubscriptionConditionAddedToChannel has status True when controller has successfully added a + // subscription to the spec.channel resource. + SubscriptionConditionAddedToChannel apis.ConditionType = "AddedToChannel" + + // SubscriptionConditionChannelReady has status True when the channel has marked the subscriber as 'ready' + SubscriptionConditionChannelReady apis.ConditionType = "ChannelReady" + + // SubscriptionConditionReplyDeprecated is used to tell the user they are using deprecated fields. + SubscriptionConditionReplyDeprecated = "Deprecated" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (ss *SubscriptionStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return subCondSet.Manage(ss).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (ss *SubscriptionStatus) IsReady() bool { + return subCondSet.Manage(ss).IsHappy() +} + +// IsAddedToChannel returns true if SubscriptionConditionAddedToChannel is true +func (ss *SubscriptionStatus) IsAddedToChannel() bool { + return ss.GetCondition(SubscriptionConditionAddedToChannel).IsTrue() +} + +// AreReferencesResolved returns true if SubscriptionConditionReferencesResolved is true +func (ss *SubscriptionStatus) AreReferencesResolved() bool { + return ss.GetCondition(SubscriptionConditionReferencesResolved).IsTrue() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (ss *SubscriptionStatus) InitializeConditions() { + subCondSet.Manage(ss).InitializeConditions() +} + +// MarkReferencesResolved sets the ReferencesResolved condition to True state. +func (ss *SubscriptionStatus) MarkReferencesResolved() { + subCondSet.Manage(ss).MarkTrue(SubscriptionConditionReferencesResolved) +} + +// MarkChannelReady sets the ChannelReady condition to True state. +func (ss *SubscriptionStatus) MarkChannelReady() { + subCondSet.Manage(ss).MarkTrue(SubscriptionConditionChannelReady) +} + +// MarkAddedToChannel sets the AddedToChannel condition to True state. +func (ss *SubscriptionStatus) MarkAddedToChannel() { + subCondSet.Manage(ss).MarkTrue(SubscriptionConditionAddedToChannel) +} + +// MarkReferencesNotResolved sets the ReferencesResolved condition to False state. +func (ss *SubscriptionStatus) MarkReferencesNotResolved(reason, messageFormat string, messageA ...interface{}) { + subCondSet.Manage(ss).MarkFalse(SubscriptionConditionReferencesResolved, reason, messageFormat, messageA...) +} + +// MarkChannelNotReady sets the ChannelReady condition to False state. +func (ss *SubscriptionStatus) MarkChannelNotReady(reason, messageFormat string, messageA ...interface{}) { + subCondSet.Manage(ss).MarkFalse(SubscriptionConditionChannelReady, reason, messageFormat, messageA) +} + +// MarkNotAddedToChannel sets the AddedToChannel condition to False state. +func (ss *SubscriptionStatus) MarkNotAddedToChannel(reason, messageFormat string, messageA ...interface{}) { + subCondSet.Manage(ss).MarkFalse(SubscriptionConditionAddedToChannel, reason, messageFormat, messageA) +} + +// MarkDeprecated adds a warning condition that this object's spec is using deprecated fields +// and will stop working in the future. Note that this does not affect the Ready condition. +func (s *SubscriptionStatus) MarkReplyDeprecatedRef(reason, msg string) { + dc := apis.Condition{ + Type: SubscriptionConditionReplyDeprecated, + Reason: reason, + Status: v1.ConditionTrue, + Severity: apis.ConditionSeverityWarning, + Message: msg, + } + for i, c := range s.Conditions { + if c.Type == dc.Type { + s.Conditions[i] = dc + return + } + } + s.Conditions = append(s.Conditions, dc) +} + +// ClearDeprecated removes the StatusConditionTypeDeprecated warning condition. Note that this does not +// affect the Ready condition. +func (s *SubscriptionStatus) ClearDeprecated() { + conds := make([]apis.Condition, 0, len(s.Conditions)) + for _, c := range s.Conditions { + if c.Type != SubscriptionConditionReplyDeprecated { + conds = append(conds, c) + } + } + s.Conditions = conds +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_types.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_types.go new file mode 100644 index 0000000000..a9fa7b0334 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_types.go @@ -0,0 +1,164 @@ +/* + * Copyright 2018 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/webhook" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:defaulter-gen=true + +// Subscription routes events received on a Channel to a DNS name and +// corresponds to the subscriptions.channels.knative.dev CRD. +type Subscription struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec SubscriptionSpec `json:"spec"` + Status SubscriptionStatus `json:"status,omitempty"` +} + +var ( + // Check that Subscription can be validated, can be defaulted, and has immutable fields. + _ apis.Validatable = (*Subscription)(nil) + _ apis.Defaultable = (*Subscription)(nil) + _ apis.Immutable = (*Subscription)(nil) + + // Check that Subscription can return its spec untyped. + _ apis.HasSpec = (*Subscription)(nil) + + _ runtime.Object = (*Subscription)(nil) + _ webhook.GenericCRD = (*Subscription)(nil) + + // Check that we can create OwnerReferences to a Subscription. + _ kmeta.OwnerRefable = (*Subscription)(nil) +) + +// SubscriptionSpec specifies the Channel for incoming events, a Subscriber target +// for processing those events and where to put the result of the processing. Only +// From (where the events are coming from) is always required. You can optionally +// only Process the events (results in no output events) by leaving out the Result. +// You can also perform an identity transformation on the incoming events by leaving +// out the Subscriber and only specifying Result. +// +// The following are all valid specifications: +// channel --[subscriber]--> reply +// Sink, no outgoing events: +// channel -- subscriber +// no-op function (identity transformation): +// channel --> reply +type SubscriptionSpec struct { + // TODO By enabling the status subresource metadata.generation should increment + // thus making this property obsolete. + // + // We should be able to drop this property with a CRD conversion webhook + // in the future + // + // +optional + DeprecatedGeneration int64 `json:"generation,omitempty"` + + // Reference to a channel that will be used to create the subscription + // for receiving events. The channel must have spec.subscriptions + // list which will then be modified accordingly. + // + // You can specify only the following fields of the ObjectReference: + // - Kind + // - APIVersion + // - Name + // The resource pointed by this ObjectReference must meet the Subscribable contract + // with a pointer to the Subscribable duck type. If the resource does not meet this contract, + // it will be reflected in the Subscription's status. + + // This field is immutable. We have no good answer on what happens to + // the events that are currently in the channel being consumed from + // and what the semantics there should be. For now, you can always + // delete the Subscription and recreate it to point to a different + // channel, giving the user more control over what semantics should + // be used (drain the channel first, possibly have events dropped, + // etc.) + Channel corev1.ObjectReference `json:"channel"` + + // Subscriber is reference to (optional) function for processing events. + // Events from the Channel will be delivered here and replies are + // sent to a channel as specified by the Reply. + // +optional + Subscriber *apisv1alpha1.Destination `json:"subscriber,omitempty"` + + // Reply specifies (optionally) how to handle events returned from + // the Subscriber target. + // +optional + Reply *ReplyStrategy `json:"reply,omitempty"` +} + +// ReplyStrategy specifies the handling of the Subscriber's returned replies. +// If no Subscriber is specified, the identity function is assumed. +type ReplyStrategy struct { + // The resource pointed by this ObjectReference must meet the Addressable contract + // with a reference to the Addressable duck type. If the resource does not meet this contract, + // it will be reflected in the Subscription's status. + // +optional + Channel *apisv1alpha1.Destination `json:"channel,omitempty"` +} + +// SubscriptionStatus (computed) for a subscription +type SubscriptionStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // PhysicalSubscription is the fully resolved values that this Subscription represents. + PhysicalSubscription SubscriptionStatusPhysicalSubscription `json:"physicalSubscription,omitempty"` +} + +// SubscriptionStatusPhysicalSubscription represents the fully resolved values for this +// Subscription. +type SubscriptionStatusPhysicalSubscription struct { + // SubscriberURI is the fully resolved URI for spec.subscriber. + SubscriberURI *apis.URL `json:"subscriberURI,omitempty"` + + // ReplyURI is the fully resolved URI for the spec.reply. + ReplyURI *apis.URL `json:"replyURI,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SubscriptionList returned in list operations +type SubscriptionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []Subscription `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for Subscriptions +func (t *Subscription) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Subscription") +} + +// GetUntypedSpec returns the spec of the Subscription. +func (s *Subscription) GetUntypedSpec() interface{} { + return s.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_validation.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_validation.go new file mode 100644 index 0000000000..a377cc281b --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/subscription_validation.go @@ -0,0 +1,102 @@ +/* +Copyright 2018 The Knative 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 v1alpha1 + +import ( + "context" + + "github.com/google/go-cmp/cmp/cmpopts" + "k8s.io/apimachinery/pkg/api/equality" + "knative.dev/pkg/apis" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" + "knative.dev/pkg/kmp" +) + +func (s *Subscription) Validate(ctx context.Context) *apis.FieldError { + return s.Spec.Validate(ctx).ViaField("spec") +} + +func (ss *SubscriptionSpec) Validate(ctx context.Context) *apis.FieldError { + // We require always Channel. + // Also at least one of 'subscriber' and 'reply' must be defined (non-nil and non-empty). + + var errs *apis.FieldError + if isChannelEmpty(ss.Channel) { + fe := apis.ErrMissingField("channel") + fe.Details = "the Subscription must reference a channel" + return fe + } else if fe := isValidChannel(ss.Channel); fe != nil { + errs = errs.Also(fe.ViaField("channel")) + } + + missingSubscriber := isDestinationNilOrEmpty(ss.Subscriber) + missingReply := isReplyStrategyNilOrEmpty(ss.Reply) + if missingSubscriber && missingReply { + fe := apis.ErrMissingField("reply", "subscriber") + fe.Details = "the Subscription must reference at least one of (reply or a subscriber)" + errs = errs.Also(fe) + } + + if !missingSubscriber { + if fe := ss.Subscriber.ValidateDisallowDeprecated(ctx); fe != nil { + errs = errs.Also(fe.ViaField("subscriber")) + } + } + + if !missingReply { + if fe := ss.Reply.Channel.Validate(ctx); fe != nil { + errs = errs.Also(fe.ViaField("reply.channel")) + } + } + + return errs +} + +func isDestinationNilOrEmpty(d *apisv1alpha1.Destination) bool { + return d == nil || equality.Semantic.DeepEqual(d, &apisv1alpha1.Destination{}) +} + +func isReplyStrategyNilOrEmpty(r *ReplyStrategy) bool { + return r == nil || equality.Semantic.DeepEqual(r, &ReplyStrategy{}) || equality.Semantic.DeepEqual(r.Channel, &apisv1alpha1.Destination{}) +} + +func (s *Subscription) CheckImmutableFields(ctx context.Context, og apis.Immutable) *apis.FieldError { + original, ok := og.(*Subscription) + if !ok { + return &apis.FieldError{Message: "The provided original was not a Subscription"} + } + if original == nil { + return nil + } + + // Only Subscriber and Reply are mutable. + ignoreArguments := cmpopts.IgnoreFields(SubscriptionSpec{}, "Subscriber", "Reply") + if diff, err := kmp.ShortDiff(original.Spec, s.Spec, ignoreArguments); err != nil { + return &apis.FieldError{ + Message: "Failed to diff Subscription", + Paths: []string{"spec"}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec"}, + Details: diff, + } + } + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/zz_generated.deepcopy.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..06f5dd4fa5 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,758 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + apis "knative.dev/pkg/apis" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Channel) DeepCopyInto(out *Channel) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Channel. +func (in *Channel) DeepCopy() *Channel { + if in == nil { + return nil + } + out := new(Channel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Channel) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelList) DeepCopyInto(out *ChannelList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Channel, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelList. +func (in *ChannelList) DeepCopy() *ChannelList { + if in == nil { + return nil + } + out := new(ChannelList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ChannelList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelSpec) DeepCopyInto(out *ChannelSpec) { + *out = *in + if in.ChannelTemplate != nil { + in, out := &in.ChannelTemplate, &out.ChannelTemplate + *out = new(duckv1alpha1.ChannelTemplateSpec) + (*in).DeepCopyInto(*out) + } + if in.Subscribable != nil { + in, out := &in.Subscribable, &out.Subscribable + *out = new(duckv1alpha1.Subscribable) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelSpec. +func (in *ChannelSpec) DeepCopy() *ChannelSpec { + if in == nil { + return nil + } + out := new(ChannelSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelStatus) DeepCopyInto(out *ChannelStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + in.AddressStatus.DeepCopyInto(&out.AddressStatus) + in.SubscribableTypeStatus.DeepCopyInto(&out.SubscribableTypeStatus) + if in.Channel != nil { + in, out := &in.Channel, &out.Channel + *out = new(v1.ObjectReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelStatus. +func (in *ChannelStatus) DeepCopy() *ChannelStatus { + if in == nil { + return nil + } + out := new(ChannelStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InMemoryChannel) DeepCopyInto(out *InMemoryChannel) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InMemoryChannel. +func (in *InMemoryChannel) DeepCopy() *InMemoryChannel { + if in == nil { + return nil + } + out := new(InMemoryChannel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *InMemoryChannel) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InMemoryChannelList) DeepCopyInto(out *InMemoryChannelList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]InMemoryChannel, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InMemoryChannelList. +func (in *InMemoryChannelList) DeepCopy() *InMemoryChannelList { + if in == nil { + return nil + } + out := new(InMemoryChannelList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *InMemoryChannelList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InMemoryChannelSpec) DeepCopyInto(out *InMemoryChannelSpec) { + *out = *in + if in.Subscribable != nil { + in, out := &in.Subscribable, &out.Subscribable + *out = new(duckv1alpha1.Subscribable) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InMemoryChannelSpec. +func (in *InMemoryChannelSpec) DeepCopy() *InMemoryChannelSpec { + if in == nil { + return nil + } + out := new(InMemoryChannelSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InMemoryChannelStatus) DeepCopyInto(out *InMemoryChannelStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + in.AddressStatus.DeepCopyInto(&out.AddressStatus) + in.SubscribableTypeStatus.DeepCopyInto(&out.SubscribableTypeStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InMemoryChannelStatus. +func (in *InMemoryChannelStatus) DeepCopy() *InMemoryChannelStatus { + if in == nil { + return nil + } + out := new(InMemoryChannelStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Parallel) DeepCopyInto(out *Parallel) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Parallel. +func (in *Parallel) DeepCopy() *Parallel { + if in == nil { + return nil + } + out := new(Parallel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Parallel) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParallelBranch) DeepCopyInto(out *ParallelBranch) { + *out = *in + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + in.Subscriber.DeepCopyInto(&out.Subscriber) + if in.Reply != nil { + in, out := &in.Reply, &out.Reply + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParallelBranch. +func (in *ParallelBranch) DeepCopy() *ParallelBranch { + if in == nil { + return nil + } + out := new(ParallelBranch) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParallelBranchStatus) DeepCopyInto(out *ParallelBranchStatus) { + *out = *in + in.FilterSubscriptionStatus.DeepCopyInto(&out.FilterSubscriptionStatus) + in.FilterChannelStatus.DeepCopyInto(&out.FilterChannelStatus) + in.SubscriptionStatus.DeepCopyInto(&out.SubscriptionStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParallelBranchStatus. +func (in *ParallelBranchStatus) DeepCopy() *ParallelBranchStatus { + if in == nil { + return nil + } + out := new(ParallelBranchStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParallelChannelStatus) DeepCopyInto(out *ParallelChannelStatus) { + *out = *in + out.Channel = in.Channel + in.ReadyCondition.DeepCopyInto(&out.ReadyCondition) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParallelChannelStatus. +func (in *ParallelChannelStatus) DeepCopy() *ParallelChannelStatus { + if in == nil { + return nil + } + out := new(ParallelChannelStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParallelList) DeepCopyInto(out *ParallelList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Parallel, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParallelList. +func (in *ParallelList) DeepCopy() *ParallelList { + if in == nil { + return nil + } + out := new(ParallelList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ParallelList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParallelSpec) DeepCopyInto(out *ParallelSpec) { + *out = *in + if in.Branches != nil { + in, out := &in.Branches, &out.Branches + *out = make([]ParallelBranch, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ChannelTemplate != nil { + in, out := &in.ChannelTemplate, &out.ChannelTemplate + *out = new(duckv1alpha1.ChannelTemplateSpec) + (*in).DeepCopyInto(*out) + } + if in.Reply != nil { + in, out := &in.Reply, &out.Reply + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParallelSpec. +func (in *ParallelSpec) DeepCopy() *ParallelSpec { + if in == nil { + return nil + } + out := new(ParallelSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParallelStatus) DeepCopyInto(out *ParallelStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + in.IngressChannelStatus.DeepCopyInto(&out.IngressChannelStatus) + if in.BranchStatuses != nil { + in, out := &in.BranchStatuses, &out.BranchStatuses + *out = make([]ParallelBranchStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.AddressStatus.DeepCopyInto(&out.AddressStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParallelStatus. +func (in *ParallelStatus) DeepCopy() *ParallelStatus { + if in == nil { + return nil + } + out := new(ParallelStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParallelSubscriptionStatus) DeepCopyInto(out *ParallelSubscriptionStatus) { + *out = *in + out.Subscription = in.Subscription + in.ReadyCondition.DeepCopyInto(&out.ReadyCondition) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParallelSubscriptionStatus. +func (in *ParallelSubscriptionStatus) DeepCopy() *ParallelSubscriptionStatus { + if in == nil { + return nil + } + out := new(ParallelSubscriptionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplyStrategy) DeepCopyInto(out *ReplyStrategy) { + *out = *in + if in.Channel != nil { + in, out := &in.Channel, &out.Channel + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplyStrategy. +func (in *ReplyStrategy) DeepCopy() *ReplyStrategy { + if in == nil { + return nil + } + out := new(ReplyStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Sequence) DeepCopyInto(out *Sequence) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sequence. +func (in *Sequence) DeepCopy() *Sequence { + if in == nil { + return nil + } + out := new(Sequence) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Sequence) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SequenceChannelStatus) DeepCopyInto(out *SequenceChannelStatus) { + *out = *in + out.Channel = in.Channel + in.ReadyCondition.DeepCopyInto(&out.ReadyCondition) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SequenceChannelStatus. +func (in *SequenceChannelStatus) DeepCopy() *SequenceChannelStatus { + if in == nil { + return nil + } + out := new(SequenceChannelStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SequenceList) DeepCopyInto(out *SequenceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Sequence, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SequenceList. +func (in *SequenceList) DeepCopy() *SequenceList { + if in == nil { + return nil + } + out := new(SequenceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SequenceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SequenceSpec) DeepCopyInto(out *SequenceSpec) { + *out = *in + if in.Steps != nil { + in, out := &in.Steps, &out.Steps + *out = make([]apisv1alpha1.Destination, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ChannelTemplate != nil { + in, out := &in.ChannelTemplate, &out.ChannelTemplate + *out = new(duckv1alpha1.ChannelTemplateSpec) + (*in).DeepCopyInto(*out) + } + if in.Reply != nil { + in, out := &in.Reply, &out.Reply + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SequenceSpec. +func (in *SequenceSpec) DeepCopy() *SequenceSpec { + if in == nil { + return nil + } + out := new(SequenceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SequenceStatus) DeepCopyInto(out *SequenceStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + if in.SubscriptionStatuses != nil { + in, out := &in.SubscriptionStatuses, &out.SubscriptionStatuses + *out = make([]SequenceSubscriptionStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ChannelStatuses != nil { + in, out := &in.ChannelStatuses, &out.ChannelStatuses + *out = make([]SequenceChannelStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.AddressStatus.DeepCopyInto(&out.AddressStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SequenceStatus. +func (in *SequenceStatus) DeepCopy() *SequenceStatus { + if in == nil { + return nil + } + out := new(SequenceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SequenceSubscriptionStatus) DeepCopyInto(out *SequenceSubscriptionStatus) { + *out = *in + out.Subscription = in.Subscription + in.ReadyCondition.DeepCopyInto(&out.ReadyCondition) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SequenceSubscriptionStatus. +func (in *SequenceSubscriptionStatus) DeepCopy() *SequenceSubscriptionStatus { + if in == nil { + return nil + } + out := new(SequenceSubscriptionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Subscription) DeepCopyInto(out *Subscription) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subscription. +func (in *Subscription) DeepCopy() *Subscription { + if in == nil { + return nil + } + out := new(Subscription) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Subscription) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionList) DeepCopyInto(out *SubscriptionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Subscription, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionList. +func (in *SubscriptionList) DeepCopy() *SubscriptionList { + if in == nil { + return nil + } + out := new(SubscriptionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SubscriptionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionSpec) DeepCopyInto(out *SubscriptionSpec) { + *out = *in + out.Channel = in.Channel + if in.Subscriber != nil { + in, out := &in.Subscriber, &out.Subscriber + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + if in.Reply != nil { + in, out := &in.Reply, &out.Reply + *out = new(ReplyStrategy) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionSpec. +func (in *SubscriptionSpec) DeepCopy() *SubscriptionSpec { + if in == nil { + return nil + } + out := new(SubscriptionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionStatus) DeepCopyInto(out *SubscriptionStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + in.PhysicalSubscription.DeepCopyInto(&out.PhysicalSubscription) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionStatus. +func (in *SubscriptionStatus) DeepCopy() *SubscriptionStatus { + if in == nil { + return nil + } + out := new(SubscriptionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubscriptionStatusPhysicalSubscription) DeepCopyInto(out *SubscriptionStatusPhysicalSubscription) { + *out = *in + if in.SubscriberURI != nil { + in, out := &in.SubscriberURI, &out.SubscriberURI + *out = new(apis.URL) + (*in).DeepCopyInto(*out) + } + if in.ReplyURI != nil { + in, out := &in.ReplyURI, &out.ReplyURI + *out = new(apis.URL) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubscriptionStatusPhysicalSubscription. +func (in *SubscriptionStatusPhysicalSubscription) DeepCopy() *SubscriptionStatusPhysicalSubscription { + if in == nil { + return nil + } + out := new(SubscriptionStatusPhysicalSubscription) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/register.go b/vendor/knative.dev/eventing/pkg/apis/sources/register.go new file mode 100644 index 0000000000..4d2a447769 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/register.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 The Knative 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 sources + +const ( + GroupName = "sources.eventing.knative.dev" +) diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_defaults.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_defaults.go new file mode 100644 index 0000000000..18891cdb98 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_defaults.go @@ -0,0 +1,29 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" +) + +func (s *ApiServerSource) SetDefaults(ctx context.Context) { + s.Spec.SetDefaults(ctx) +} + +func (ss *ApiServerSourceSpec) SetDefaults(ctx context.Context) { + // TODO anything? +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_lifecycle.go new file mode 100644 index 0000000000..0a782a8836 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_lifecycle.go @@ -0,0 +1,113 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + + "knative.dev/pkg/apis" + + "knative.dev/eventing/pkg/apis/duck" +) + +const ( + // ApiServerConditionReady has status True when the ApiServerSource is ready to send events. + ApiServerConditionReady = apis.ConditionReady + + // ApiServerConditionSinkProvided has status True when the ApiServerSource has been configured with a sink target. + ApiServerConditionSinkProvided apis.ConditionType = "SinkProvided" + + // ApiServerConditionDeployed has status True when the ApiServerSource has had it's deployment created. + ApiServerConditionDeployed apis.ConditionType = "Deployed" + + // ApiServerConditionEventTypeProvided has status True when the ApiServerSource has been configured with its event types. + ApiServerConditionEventTypeProvided apis.ConditionType = "EventTypesProvided" +) + +var apiserverCondSet = apis.NewLivingConditionSet( + ApiServerConditionSinkProvided, + ApiServerConditionDeployed, +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (s *ApiServerSourceStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return apiserverCondSet.Manage(s).GetCondition(t) +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (s *ApiServerSourceStatus) InitializeConditions() { + apiserverCondSet.Manage(s).InitializeConditions() +} + +// MarkSink sets the condition that the source has a sink configured. +func (s *ApiServerSourceStatus) MarkSink(uri string) { + s.SinkURI = uri + if len(uri) > 0 { + apiserverCondSet.Manage(s).MarkTrue(ApiServerConditionSinkProvided) + } else { + apiserverCondSet.Manage(s).MarkUnknown(ApiServerConditionSinkProvided, "SinkEmpty", "Sink has resolved to empty.%s", "") + } +} + +// MarkSinkWarnDeprecated sets the condition that the source has a sink configured and warns ref is deprecated. +func (s *ApiServerSourceStatus) MarkSinkWarnRefDeprecated(uri string) { + s.SinkURI = uri + if len(uri) > 0 { + c := apis.Condition{ + Type: ApiServerConditionSinkProvided, + Status: corev1.ConditionTrue, + Severity: apis.ConditionSeverityError, + Message: "Using deprecated object ref fields when specifying spec.sink. Update to spec.sink.ref. These will be removed in 0.11.", + } + apiserverCondSet.Manage(s).SetCondition(c) + } else { + apiserverCondSet.Manage(s).MarkUnknown(ApiServerConditionSinkProvided, "SinkEmpty", "Sink has resolved to empty.%s", "") + } +} + +// MarkNoSink sets the condition that the source does not have a sink configured. +func (s *ApiServerSourceStatus) MarkNoSink(reason, messageFormat string, messageA ...interface{}) { + apiserverCondSet.Manage(s).MarkFalse(ApiServerConditionSinkProvided, reason, messageFormat, messageA...) +} + +// PropagateDeploymentAvailability uses the availability of the provided Deployment to determine if +// ApiServerConditionDeployed should be marked as true or false. +func (s *ApiServerSourceStatus) PropagateDeploymentAvailability(d *appsv1.Deployment) { + if duck.DeploymentIsAvailable(&d.Status, false) { + apiserverCondSet.Manage(s).MarkTrue(ApiServerConditionDeployed) + } else { + // I don't know how to propagate the status well, so just give the name of the Deployment + // for now. + apiserverCondSet.Manage(s).MarkFalse(ApiServerConditionDeployed, "DeploymentUnavailable", "The Deployment '%s' is unavailable.", d.Name) + } +} + +// MarkEventTypes sets the condition that the source has set its event type. +func (s *ApiServerSourceStatus) MarkEventTypes() { + apiserverCondSet.Manage(s).MarkTrue(ApiServerConditionEventTypeProvided) +} + +// MarkNoEventTypes sets the condition that the source does not its event type configured. +func (s *ApiServerSourceStatus) MarkNoEventTypes(reason, messageFormat string, messageA ...interface{}) { + apiserverCondSet.Manage(s).MarkFalse(ApiServerConditionEventTypeProvided, reason, messageFormat, messageA...) +} + +// IsReady returns true if the resource is ready overall. +func (s *ApiServerSourceStatus) IsReady() bool { + return apiserverCondSet.Manage(s).IsHappy() +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_types.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_types.go new file mode 100644 index 0000000000..adf4f3c3ca --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_types.go @@ -0,0 +1,134 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" + "knative.dev/pkg/kmeta" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ApiServerSource is the Schema for the apiserversources API +type ApiServerSource struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ApiServerSourceSpec `json:"spec,omitempty"` + Status ApiServerSourceStatus `json:"status,omitempty"` +} + +var ( + // Check that we can create OwnerReferences to an ApiServerSource. + _ kmeta.OwnerRefable = (*ApiServerSource)(nil) + + // Check that ApiServerSource can return its spec untyped. + _ apis.HasSpec = (*ApiServerSource)(nil) +) + +const ( + // ApiServerSourceAddEventType is the ApiServerSource CloudEvent type for adds. + ApiServerSourceAddEventType = "dev.knative.apiserver.resource.add" + // ApiServerSourceUpdateEventType is the ApiServerSource CloudEvent type for updates. + ApiServerSourceUpdateEventType = "dev.knative.apiserver.resource.update" + // ApiServerSourceDeleteEventType is the ApiServerSource CloudEvent type for deletions. + ApiServerSourceDeleteEventType = "dev.knative.apiserver.resource.delete" + + // ApiServerSourceAddRefEventType is the ApiServerSource CloudEvent type for ref adds. + ApiServerSourceAddRefEventType = "dev.knative.apiserver.ref.add" + // ApiServerSourceUpdateRefEventType is the ApiServerSource CloudEvent type for ref updates. + ApiServerSourceUpdateRefEventType = "dev.knative.apiserver.ref.update" + // ApiServerSourceDeleteRefEventType is the ApiServerSource CloudEvent type for ref deletions. + ApiServerSourceDeleteRefEventType = "dev.knative.apiserver.ref.delete" +) + +// GetGroupVersionKind returns the GroupVersionKind. +func (s *ApiServerSource) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("ApiServerSource") +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ApiServerSourceList contains a list of ApiServerSource +type ApiServerSourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ApiServerSource `json:"items"` +} + +// ApiServerSourceSpec defines the desired state of ApiServerSource +type ApiServerSourceSpec struct { + // Resources is the list of resources to watch + Resources []ApiServerResource `json:"resources"` + + // ServiceAccountName is the name of the ServiceAccount to use to run this + // source. + // +optional + ServiceAccountName string `json:"serviceAccountName,omitempty"` + + // Sink is a reference to an object that will resolve to a domain name to use as the sink. + // +optional + Sink *apisv1alpha1.Destination `json:"sink,omitempty"` + + // Mode is the mode the receive adapter controller runs under: Ref or Resource. + // `Ref` sends only the reference to the resource. + // `Resource` send the full resource. + Mode string `json:"mode,omitempty"` +} + +// ApiServerSourceStatus defines the observed state of ApiServerSource +type ApiServerSourceStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // SinkURI is the current active sink URI that has been configured for the ApiServerSource. + // +optional + SinkURI string `json:"sinkUri,omitempty"` +} + +// ApiServerResource defines the resource to watch +type ApiServerResource struct { + // API version of the resource to watch. + APIVersion string `json:"apiVersion"` + + // Kind of the resource to watch. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + Kind string `json:"kind"` + + // LabelSelector restricts this source to objects with the selected labels + // More info: http://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + LabelSelector metav1.LabelSelector `json:"labelSelector"` + + // ControllerSelector restricts this source to objects with a controlling owner reference of the specified kind. + // Only apiVersion and kind are used. Both are optional. + ControllerSelector metav1.OwnerReference `json:"controllerSelector"` + + // If true, send an event referencing the object controlling the resource + Controller bool `json:"controller"` +} + +// GetUntypedSpec returns the spec of the ApiServerSource. +func (a *ApiServerSource) GetUntypedSpec() interface{} { + return a.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_validation.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_validation.go new file mode 100644 index 0000000000..0987c19076 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/apiserver_validation.go @@ -0,0 +1,56 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + "knative.dev/pkg/apis" +) + +const ( + // RefMode produces payloads of ObjectReference + RefMode = "Ref" + // ResourceMode produces payloads of ResourceEvent + ResourceMode = "Resource" +) + +func (c *ApiServerSource) Validate(ctx context.Context) *apis.FieldError { + return c.Spec.Validate(ctx).ViaField("spec") +} + +func (cs *ApiServerSourceSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + + // Validate mode, if can be empty or set as certain value + if cs.Mode != "" && cs.Mode != RefMode && cs.Mode != ResourceMode { + fe := &apis.FieldError{ + Message: "Mode is not valid", + Paths: []string{"mode"}, + } + errs = errs.Also(fe) + } + + // Validate sink + if cs.Sink == nil { + fe := apis.ErrMissingField("sink") + errs = errs.Also(fe) + } else if fe := cs.Sink.Validate(ctx); fe != nil { + errs = errs.Also(fe.ViaField("sink")) + } + return errs +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_defaults.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_defaults.go new file mode 100644 index 0000000000..d9918e3897 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_defaults.go @@ -0,0 +1,29 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" +) + +func (s *ContainerSource) SetDefaults(ctx context.Context) { + s.Spec.SetDefaults(ctx) +} + +func (ss *ContainerSourceSpec) SetDefaults(ctx context.Context) { + // TODO anything? +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_lifecycle.go new file mode 100644 index 0000000000..1428616066 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_lifecycle.go @@ -0,0 +1,109 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + "knative.dev/pkg/apis" +) + +const ( + // ContainerSourceConditionReady has status True when the ContainerSource is ready to send events. + ContainerConditionReady = apis.ConditionReady + + // ContainerConditionSinkProvided has status True when the ContainerSource has been configured with a sink target. + ContainerConditionSinkProvided apis.ConditionType = "SinkProvided" + + // ContainerConditionDeployed has status True when the ContainerSource has had it's deployment created. + ContainerConditionDeployed apis.ConditionType = "Deployed" +) + +var containerCondSet = apis.NewLivingConditionSet( + ContainerConditionSinkProvided, + ContainerConditionDeployed, +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (s *ContainerSourceStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return containerCondSet.Manage(s).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (s *ContainerSourceStatus) IsReady() bool { + return containerCondSet.Manage(s).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (s *ContainerSourceStatus) InitializeConditions() { + containerCondSet.Manage(s).InitializeConditions() +} + +// MarkSink sets the condition that the source has a sink configured. +func (s *ContainerSourceStatus) MarkSink(uri string) { + s.SinkURI = uri + if len(uri) > 0 { + containerCondSet.Manage(s).MarkTrue(ContainerConditionSinkProvided) + } else { + containerCondSet.Manage(s).MarkUnknown(ContainerConditionSinkProvided, "SinkEmpty", "Sink has resolved to empty.%s", "") + } +} + +// MarkSinkWarnDeprecated sets the condition that the source has a sink configured and warns ref is deprecated. +func (s *ContainerSourceStatus) MarkSinkWarnRefDeprecated(uri string) { + s.SinkURI = uri + if len(uri) > 0 { + c := apis.Condition{ + Type: ContainerConditionSinkProvided, + Status: corev1.ConditionTrue, + Severity: apis.ConditionSeverityError, + Message: "Using deprecated object ref fields when specifying spec.sink. Update to spec.sink.ref. These will be removed in 0.11.", + } + apiserverCondSet.Manage(s).SetCondition(c) + } else { + apiserverCondSet.Manage(s).MarkUnknown(ContainerConditionSinkProvided, "SinkEmpty", "Sink has resolved to empty.%s", "") + } +} + +// MarkNoSink sets the condition that the source does not have a sink configured. +func (s *ContainerSourceStatus) MarkNoSink(reason, messageFormat string, messageA ...interface{}) { + containerCondSet.Manage(s).MarkFalse(ContainerConditionSinkProvided, reason, messageFormat, messageA...) +} + +// IsDeployed returns true if the Deployed condition has status true, otherwise +// false. +func (s *ContainerSourceStatus) IsDeployed() bool { + c := containerCondSet.Manage(s).GetCondition(ContainerConditionDeployed) + if c != nil { + return c.IsTrue() + } + return false +} + +// MarkDeployed sets the condition that the source has been deployed. +func (s *ContainerSourceStatus) MarkDeployed() { + containerCondSet.Manage(s).MarkTrue(ContainerConditionDeployed) +} + +// MarkDeploying sets the condition that the source is deploying. +func (s *ContainerSourceStatus) MarkDeploying(reason, messageFormat string, messageA ...interface{}) { + containerCondSet.Manage(s).MarkUnknown(ContainerConditionDeployed, reason, messageFormat, messageA...) +} + +// MarkNotDeployed sets the condition that the source has not been deployed. +func (s *ContainerSourceStatus) MarkNotDeployed(reason, messageFormat string, messageA ...interface{}) { + containerCondSet.Manage(s).MarkFalse(ContainerConditionDeployed, reason, messageFormat, messageA...) +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_types.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_types.go new file mode 100644 index 0000000000..90f776b775 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_types.go @@ -0,0 +1,119 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" + "knative.dev/pkg/kmeta" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:defaulter-gen=true + +// ContainerSource is the Schema for the containersources API +type ContainerSource struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ContainerSourceSpec `json:"spec,omitempty"` + Status ContainerSourceStatus `json:"status,omitempty"` +} + +var ( + _ runtime.Object = (*ContainerSource)(nil) + + // Check that we can create OwnerReferences to a ContainerSource. + _ kmeta.OwnerRefable = (*ContainerSource)(nil) + + // Check that ContainerSource can return its spec untyped. + _ apis.HasSpec = (*ContainerSource)(nil) +) + +// ContainerSourceSpec defines the desired state of ContainerSource +type ContainerSourceSpec struct { + // Template describes the pods that will be created + // +optional + Template *corev1.PodTemplateSpec `json:"template,omitempty"` + + // DeprecatedImage is the image to run inside of the container. + // This field is to be deprecated. Use `Template` instead. + // When `Template` is set, this field is ignored. + // +kubebuilder:validation:MinLength=1 + DeprecatedImage string `json:"image,omitempty"` + + // DeprecatedArgs are passed to the ContainerSpec as they are. + // This field is to be deprecated. Use `Template` instead. + // When `Template` is set, this field is ignored. + DeprecatedArgs []string `json:"args,omitempty"` + + // DeprecatedEnv is the list of environment variables to set in the container. + // Cannot be updated. + // This field is to be deprecated. Use `Template` instead. + // When `Template` is set, this field is ignored. + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + DeprecatedEnv []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name"` + + // DeprecatedServiceAccountName is the name of the ServiceAccount to use to run this + // source. + // This field is to be deprecated. Use `Template` instead. + // When `Template` is set, this field is ignored. + // +optional + DeprecatedServiceAccountName string `json:"serviceAccountName,omitempty"` + + // Sink is a reference to an object that will resolve to a domain name to use as the sink. + Sink *apisv1alpha1.Destination `json:"sink,omitempty"` +} + +// GetGroupVersionKind returns the GroupVersionKind. +func (s *ContainerSource) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("ContainerSource") +} + +// ContainerSourceStatus defines the observed state of ContainerSource +type ContainerSourceStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // SinkURI is the current active sink URI that has been configured for the ContainerSource. + // +optional + SinkURI string `json:"sinkUri,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ContainerSourceList contains a list of ContainerSource +type ContainerSourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ContainerSource `json:"items"` +} + +// GetUntypedSpec returns the spec of the ContainerSource. +func (c *ContainerSource) GetUntypedSpec() interface{} { + return c.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_validation.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_validation.go new file mode 100644 index 0000000000..5d4f9c6d7c --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/containersource_validation.go @@ -0,0 +1,38 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + "knative.dev/pkg/apis" +) + +func (c *ContainerSource) Validate(ctx context.Context) *apis.FieldError { + return c.Spec.Validate(ctx).ViaField("spec") +} + +func (cs *ContainerSourceSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + if cs.Sink == nil { + fe := apis.ErrMissingField("sink") + errs = errs.Also(fe) + } else if fe := cs.Sink.Validate(ctx); fe != nil { + errs = errs.Also(fe.ViaField("sink")) + } + return errs +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_defaults.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_defaults.go new file mode 100644 index 0000000000..25a58dbf19 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_defaults.go @@ -0,0 +1,29 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" +) + +func (s *CronJobSource) SetDefaults(ctx context.Context) { + s.Spec.SetDefaults(ctx) +} + +func (ss *CronJobSourceSpec) SetDefaults(ctx context.Context) { + // TODO anything? +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_lifecycle.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_lifecycle.go new file mode 100644 index 0000000000..fc92cde65c --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_lifecycle.go @@ -0,0 +1,141 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + + "knative.dev/pkg/apis" + + "knative.dev/eventing/pkg/apis/duck" +) + +const ( + // CronJobConditionReady has status True when the CronJobSource is ready to send events. + CronJobConditionReady = apis.ConditionReady + + // CronJobConditionValidSchedule has status True when the CronJobSource has been configured with a valid schedule. + CronJobConditionValidSchedule apis.ConditionType = "ValidSchedule" + + // CronJobConditionSinkProvided has status True when the CronJobSource has been configured with a sink target. + CronJobConditionSinkProvided apis.ConditionType = "SinkProvided" + + // CronJobConditionDeployed has status True when the CronJobSource has had it's receive adapter deployment created. + CronJobConditionDeployed apis.ConditionType = "Deployed" + + // CronJobConditionEventTypeProvided has status True when the CronJobSource has been configured with its event type. + CronJobConditionEventTypeProvided apis.ConditionType = "EventTypeProvided" + + // CronJobConditionResources is True when the resources listed for the CronJobSource have been properly + // parsed and match specified syntax for resource quantities + CronJobConditionResources apis.ConditionType = "ResourcesCorrect" +) + +var cronJobSourceCondSet = apis.NewLivingConditionSet( + CronJobConditionValidSchedule, + CronJobConditionSinkProvided, + CronJobConditionDeployed) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (s *CronJobSourceStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return cronJobSourceCondSet.Manage(s).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (s *CronJobSourceStatus) IsReady() bool { + return cronJobSourceCondSet.Manage(s).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (s *CronJobSourceStatus) InitializeConditions() { + cronJobSourceCondSet.Manage(s).InitializeConditions() +} + +// TODO: this is a bad method name, change it. +// MarkSchedule sets the condition that the source has a valid schedule configured. +func (s *CronJobSourceStatus) MarkSchedule() { + cronJobSourceCondSet.Manage(s).MarkTrue(CronJobConditionValidSchedule) +} + +// MarkInvalidSchedule sets the condition that the source does not have a valid schedule configured. +func (s *CronJobSourceStatus) MarkInvalidSchedule(reason, messageFormat string, messageA ...interface{}) { + cronJobSourceCondSet.Manage(s).MarkFalse(CronJobConditionValidSchedule, reason, messageFormat, messageA...) +} + +// MarkSink sets the condition that the source has a sink configured. +func (s *CronJobSourceStatus) MarkSink(uri string) { + s.SinkURI = uri + if len(uri) > 0 { + cronJobSourceCondSet.Manage(s).MarkTrue(CronJobConditionSinkProvided) + } else { + cronJobSourceCondSet.Manage(s).MarkUnknown(CronJobConditionSinkProvided, "SinkEmpty", "Sink has resolved to empty.%s", "") + } +} + +// MarkSinkWarnDeprecated sets the condition that the source has a sink configured and warns ref is deprecated. +func (s *CronJobSourceStatus) MarkSinkWarnRefDeprecated(uri string) { + s.SinkURI = uri + if len(uri) > 0 { + c := apis.Condition{ + Type: CronJobConditionSinkProvided, + Status: corev1.ConditionTrue, + Severity: apis.ConditionSeverityError, + Message: "Using deprecated object ref fields when specifying spec.sink. Update to spec.sink.ref. These will be removed in 0.11.", + } + apiserverCondSet.Manage(s).SetCondition(c) + } else { + apiserverCondSet.Manage(s).MarkUnknown(CronJobConditionSinkProvided, "SinkEmpty", "Sink has resolved to empty.%s", "") + } +} + +// MarkNoSink sets the condition that the source does not have a sink configured. +func (s *CronJobSourceStatus) MarkNoSink(reason, messageFormat string, messageA ...interface{}) { + cronJobSourceCondSet.Manage(s).MarkFalse(CronJobConditionSinkProvided, reason, messageFormat, messageA...) +} + +// PropagateDeploymentAvailability uses the availability of the provided Deployment to determine if +// CronJobConditionDeployed should be marked as true or false. +func (s *CronJobSourceStatus) PropagateDeploymentAvailability(d *appsv1.Deployment) { + if duck.DeploymentIsAvailable(&d.Status, false) { + cronJobSourceCondSet.Manage(s).MarkTrue(CronJobConditionDeployed) + } else { + // I don't know how to propagate the status well, so just give the name of the Deployment + // for now. + cronJobSourceCondSet.Manage(s).MarkFalse(CronJobConditionDeployed, "DeploymentUnavailable", "The Deployment '%s' is unavailable.", d.Name) + } +} + +// MarkEventType sets the condition that the source has set its event type. +func (s *CronJobSourceStatus) MarkEventType() { + cronJobSourceCondSet.Manage(s).MarkTrue(CronJobConditionEventTypeProvided) +} + +// MarkNoEventType sets the condition that the source does not its event type configured. +func (s *CronJobSourceStatus) MarkNoEventType(reason, messageFormat string, messageA ...interface{}) { + cronJobSourceCondSet.Manage(s).MarkFalse(CronJobConditionEventTypeProvided, reason, messageFormat, messageA...) +} + +// MarkResourcesCorrect sets the condition that the source resources are properly parsable quantities +func (s *CronJobSourceStatus) MarkResourcesCorrect() { + cronJobSourceCondSet.Manage(s).MarkTrue(CronJobConditionResources) +} + +// MarkResourcesIncorrect sets the condition that the source resources are not properly parsable quantities +func (s *CronJobSourceStatus) MarkResourcesIncorrect(reason, messageFormat string, messageA ...interface{}) { + cronJobSourceCondSet.Manage(s).MarkFalse(CronJobConditionResources, reason, messageFormat, messageA...) +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_types.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_types.go new file mode 100644 index 0000000000..8d8a7564b2 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_types.go @@ -0,0 +1,132 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "fmt" + + "knative.dev/pkg/apis" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + duckv1 "knative.dev/pkg/apis/duck/v1" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" + "knative.dev/pkg/kmeta" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:defaulter-gen=true + +// CronJobSource is the Schema for the cronjobsources API. +type CronJobSource struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CronJobSourceSpec `json:"spec,omitempty"` + Status CronJobSourceStatus `json:"status,omitempty"` +} + +// TODO: Check that CronJobSource can be validated and can be defaulted. + +var ( + // Check that it is a runtime object. + _ runtime.Object = (*CronJobSource)(nil) + + // Check that we can create OwnerReferences to a CronJobSource. + _ kmeta.OwnerRefable = (*CronJobSource)(nil) + + // Check that CronJobSource can return its spec untyped. + _ apis.HasSpec = (*CronJobSource)(nil) +) + +const ( + // CronJobEventType is the CronJob CloudEvent type. + CronJobEventType = "dev.knative.cronjob.event" +) + +// CronJobEventSource returns the CronJob CloudEvent source. +func CronJobEventSource(namespace, cronJobName string) string { + return fmt.Sprintf("/apis/v1/namespaces/%s/cronjobsources/%s", namespace, cronJobName) +} + +type CronJobRequestsSpec struct { + ResourceCPU string `json:"cpu,omitempty"` + ResourceMemory string `json:"memory,omitempty"` +} + +type CronJobLimitsSpec struct { + ResourceCPU string `json:"cpu,omitempty"` + ResourceMemory string `json:"memory,omitempty"` +} + +type CronJobResourceSpec struct { + Requests CronJobRequestsSpec `json:"requests,omitempty"` + Limits CronJobLimitsSpec `json:"limits,omitempty"` +} + +// CronJobSourceSpec defines the desired state of the CronJobSource. +type CronJobSourceSpec struct { + // Schedule is the cronjob schedule. + // +required + Schedule string `json:"schedule"` + + // Data is the data posted to the target function. + Data string `json:"data,omitempty"` + + // Sink is a reference to an object that will resolve to a domain name to use as the sink. + Sink *apisv1alpha1.Destination `json:"sink,omitempty"` + + // ServiceAccoutName is the name of the ServiceAccount that will be used to run the Receive + // Adapter Deployment. + ServiceAccountName string `json:"serviceAccountName,omitempty"` + + // Resource limits and Request specifications of the Receive Adapter Deployment + Resources CronJobResourceSpec `json:"resources,omitempty"` +} + +// GetGroupVersionKind returns the GroupVersionKind. +func (s *CronJobSource) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("CronJobSource") +} + +// CronJobSourceStatus defines the observed state of CronJobSource. +type CronJobSourceStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` + + // SinkURI is the current active sink URI that has been configured for the CronJobSource. + // +optional + SinkURI string `json:"sinkUri,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CronJobSourceList contains a list of CronJobSources. +type CronJobSourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []CronJobSource `json:"items"` +} + +// GetUntypedSpec returns the spec of the CronJobSource. +func (c *CronJobSource) GetUntypedSpec() interface{} { + return c.Spec +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_validation.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_validation.go new file mode 100644 index 0000000000..d268f53193 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/cron_job_validation.go @@ -0,0 +1,45 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + + "github.com/robfig/cron" + "knative.dev/pkg/apis" +) + +func (c *CronJobSource) Validate(ctx context.Context) *apis.FieldError { + return c.Spec.Validate(ctx).ViaField("spec") +} + +func (cs *CronJobSourceSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + + if _, err := cron.ParseStandard(cs.Schedule); err != nil { + fe := apis.ErrInvalidValue(cs.Schedule, "schedule") + errs = errs.Also(fe) + } + + if cs.Sink == nil { + fe := apis.ErrMissingField("sink") + errs = errs.Also(fe) + } else if fe := cs.Sink.Validate(ctx); fe != nil { + errs = errs.Also(fe.ViaField("sink")) + } + return errs +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/doc.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/doc.go new file mode 100644 index 0000000000..7d7f6738fb --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 contains API Schema definitions for the sources v1alpha1 API group +// +k8s:deepcopy-gen=package +// +groupName=sources.eventing.knative.dev +package v1alpha1 diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/register.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/register.go new file mode 100644 index 0000000000..1f4f6e0370 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/register.go @@ -0,0 +1,57 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "knative.dev/eventing/pkg/apis/sources" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: sources.GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CronJobSource{}, + &CronJobSourceList{}, + &ContainerSource{}, + &ContainerSourceList{}, + &ApiServerSource{}, + &ApiServerSourceList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/zz_generated.deepcopy.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..e71a4ccb3a --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,417 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + apisv1alpha1 "knative.dev/pkg/apis/v1alpha1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApiServerResource) DeepCopyInto(out *ApiServerResource) { + *out = *in + in.LabelSelector.DeepCopyInto(&out.LabelSelector) + in.ControllerSelector.DeepCopyInto(&out.ControllerSelector) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApiServerResource. +func (in *ApiServerResource) DeepCopy() *ApiServerResource { + if in == nil { + return nil + } + out := new(ApiServerResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApiServerSource) DeepCopyInto(out *ApiServerSource) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApiServerSource. +func (in *ApiServerSource) DeepCopy() *ApiServerSource { + if in == nil { + return nil + } + out := new(ApiServerSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ApiServerSource) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApiServerSourceList) DeepCopyInto(out *ApiServerSourceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ApiServerSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApiServerSourceList. +func (in *ApiServerSourceList) DeepCopy() *ApiServerSourceList { + if in == nil { + return nil + } + out := new(ApiServerSourceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ApiServerSourceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApiServerSourceSpec) DeepCopyInto(out *ApiServerSourceSpec) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]ApiServerResource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Sink != nil { + in, out := &in.Sink, &out.Sink + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApiServerSourceSpec. +func (in *ApiServerSourceSpec) DeepCopy() *ApiServerSourceSpec { + if in == nil { + return nil + } + out := new(ApiServerSourceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApiServerSourceStatus) DeepCopyInto(out *ApiServerSourceStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApiServerSourceStatus. +func (in *ApiServerSourceStatus) DeepCopy() *ApiServerSourceStatus { + if in == nil { + return nil + } + out := new(ApiServerSourceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerSource) DeepCopyInto(out *ContainerSource) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerSource. +func (in *ContainerSource) DeepCopy() *ContainerSource { + if in == nil { + return nil + } + out := new(ContainerSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ContainerSource) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerSourceList) DeepCopyInto(out *ContainerSourceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ContainerSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerSourceList. +func (in *ContainerSourceList) DeepCopy() *ContainerSourceList { + if in == nil { + return nil + } + out := new(ContainerSourceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ContainerSourceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerSourceSpec) DeepCopyInto(out *ContainerSourceSpec) { + *out = *in + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(v1.PodTemplateSpec) + (*in).DeepCopyInto(*out) + } + if in.DeprecatedArgs != nil { + in, out := &in.DeprecatedArgs, &out.DeprecatedArgs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.DeprecatedEnv != nil { + in, out := &in.DeprecatedEnv, &out.DeprecatedEnv + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Sink != nil { + in, out := &in.Sink, &out.Sink + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerSourceSpec. +func (in *ContainerSourceSpec) DeepCopy() *ContainerSourceSpec { + if in == nil { + return nil + } + out := new(ContainerSourceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerSourceStatus) DeepCopyInto(out *ContainerSourceStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerSourceStatus. +func (in *ContainerSourceStatus) DeepCopy() *ContainerSourceStatus { + if in == nil { + return nil + } + out := new(ContainerSourceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronJobLimitsSpec) DeepCopyInto(out *CronJobLimitsSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobLimitsSpec. +func (in *CronJobLimitsSpec) DeepCopy() *CronJobLimitsSpec { + if in == nil { + return nil + } + out := new(CronJobLimitsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronJobRequestsSpec) DeepCopyInto(out *CronJobRequestsSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobRequestsSpec. +func (in *CronJobRequestsSpec) DeepCopy() *CronJobRequestsSpec { + if in == nil { + return nil + } + out := new(CronJobRequestsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronJobResourceSpec) DeepCopyInto(out *CronJobResourceSpec) { + *out = *in + out.Requests = in.Requests + out.Limits = in.Limits + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobResourceSpec. +func (in *CronJobResourceSpec) DeepCopy() *CronJobResourceSpec { + if in == nil { + return nil + } + out := new(CronJobResourceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronJobSource) DeepCopyInto(out *CronJobSource) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobSource. +func (in *CronJobSource) DeepCopy() *CronJobSource { + if in == nil { + return nil + } + out := new(CronJobSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CronJobSource) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronJobSourceList) DeepCopyInto(out *CronJobSourceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CronJobSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobSourceList. +func (in *CronJobSourceList) DeepCopy() *CronJobSourceList { + if in == nil { + return nil + } + out := new(CronJobSourceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CronJobSourceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronJobSourceSpec) DeepCopyInto(out *CronJobSourceSpec) { + *out = *in + if in.Sink != nil { + in, out := &in.Sink, &out.Sink + *out = new(apisv1alpha1.Destination) + (*in).DeepCopyInto(*out) + } + out.Resources = in.Resources + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobSourceSpec. +func (in *CronJobSourceSpec) DeepCopy() *CronJobSourceSpec { + if in == nil { + return nil + } + out := new(CronJobSourceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronJobSourceStatus) DeepCopyInto(out *CronJobSourceStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobSourceStatus. +func (in *CronJobSourceStatus) DeepCopy() *CronJobSourceStatus { + if in == nil { + return nil + } + out := new(CronJobSourceStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/scheme/doc.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/scheme/doc.go new file mode 100644 index 0000000000..7d76538485 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/scheme/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/scheme/register.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/scheme/register.go new file mode 100644 index 0000000000..badcd878f1 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/scheme/register.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package scheme + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" + sourcesv1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + eventingv1alpha1.AddToScheme, + messagingv1alpha1.AddToScheme, + sourcesv1alpha1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/apiserversource.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/apiserversource.go new file mode 100644 index 0000000000..d0a6c4ef93 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/apiserversource.go @@ -0,0 +1,191 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" + scheme "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +// ApiServerSourcesGetter has a method to return a ApiServerSourceInterface. +// A group's client should implement this interface. +type ApiServerSourcesGetter interface { + ApiServerSources(namespace string) ApiServerSourceInterface +} + +// ApiServerSourceInterface has methods to work with ApiServerSource resources. +type ApiServerSourceInterface interface { + Create(*v1alpha1.ApiServerSource) (*v1alpha1.ApiServerSource, error) + Update(*v1alpha1.ApiServerSource) (*v1alpha1.ApiServerSource, error) + UpdateStatus(*v1alpha1.ApiServerSource) (*v1alpha1.ApiServerSource, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.ApiServerSource, error) + List(opts v1.ListOptions) (*v1alpha1.ApiServerSourceList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ApiServerSource, err error) + ApiServerSourceExpansion +} + +// apiServerSources implements ApiServerSourceInterface +type apiServerSources struct { + client rest.Interface + ns string +} + +// newApiServerSources returns a ApiServerSources +func newApiServerSources(c *SourcesV1alpha1Client, namespace string) *apiServerSources { + return &apiServerSources{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the apiServerSource, and returns the corresponding apiServerSource object, and an error if there is any. +func (c *apiServerSources) Get(name string, options v1.GetOptions) (result *v1alpha1.ApiServerSource, err error) { + result = &v1alpha1.ApiServerSource{} + err = c.client.Get(). + Namespace(c.ns). + Resource("apiserversources"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ApiServerSources that match those selectors. +func (c *apiServerSources) List(opts v1.ListOptions) (result *v1alpha1.ApiServerSourceList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ApiServerSourceList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("apiserversources"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested apiServerSources. +func (c *apiServerSources) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("apiserversources"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a apiServerSource and creates it. Returns the server's representation of the apiServerSource, and an error, if there is any. +func (c *apiServerSources) Create(apiServerSource *v1alpha1.ApiServerSource) (result *v1alpha1.ApiServerSource, err error) { + result = &v1alpha1.ApiServerSource{} + err = c.client.Post(). + Namespace(c.ns). + Resource("apiserversources"). + Body(apiServerSource). + Do(). + Into(result) + return +} + +// Update takes the representation of a apiServerSource and updates it. Returns the server's representation of the apiServerSource, and an error, if there is any. +func (c *apiServerSources) Update(apiServerSource *v1alpha1.ApiServerSource) (result *v1alpha1.ApiServerSource, err error) { + result = &v1alpha1.ApiServerSource{} + err = c.client.Put(). + Namespace(c.ns). + Resource("apiserversources"). + Name(apiServerSource.Name). + Body(apiServerSource). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *apiServerSources) UpdateStatus(apiServerSource *v1alpha1.ApiServerSource) (result *v1alpha1.ApiServerSource, err error) { + result = &v1alpha1.ApiServerSource{} + err = c.client.Put(). + Namespace(c.ns). + Resource("apiserversources"). + Name(apiServerSource.Name). + SubResource("status"). + Body(apiServerSource). + Do(). + Into(result) + return +} + +// Delete takes name of the apiServerSource and deletes it. Returns an error if one occurs. +func (c *apiServerSources) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("apiserversources"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *apiServerSources) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("apiserversources"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched apiServerSource. +func (c *apiServerSources) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ApiServerSource, err error) { + result = &v1alpha1.ApiServerSource{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("apiserversources"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/containersource.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/containersource.go new file mode 100644 index 0000000000..d4b0e5c810 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/containersource.go @@ -0,0 +1,191 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" + scheme "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +// ContainerSourcesGetter has a method to return a ContainerSourceInterface. +// A group's client should implement this interface. +type ContainerSourcesGetter interface { + ContainerSources(namespace string) ContainerSourceInterface +} + +// ContainerSourceInterface has methods to work with ContainerSource resources. +type ContainerSourceInterface interface { + Create(*v1alpha1.ContainerSource) (*v1alpha1.ContainerSource, error) + Update(*v1alpha1.ContainerSource) (*v1alpha1.ContainerSource, error) + UpdateStatus(*v1alpha1.ContainerSource) (*v1alpha1.ContainerSource, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.ContainerSource, error) + List(opts v1.ListOptions) (*v1alpha1.ContainerSourceList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ContainerSource, err error) + ContainerSourceExpansion +} + +// containerSources implements ContainerSourceInterface +type containerSources struct { + client rest.Interface + ns string +} + +// newContainerSources returns a ContainerSources +func newContainerSources(c *SourcesV1alpha1Client, namespace string) *containerSources { + return &containerSources{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the containerSource, and returns the corresponding containerSource object, and an error if there is any. +func (c *containerSources) Get(name string, options v1.GetOptions) (result *v1alpha1.ContainerSource, err error) { + result = &v1alpha1.ContainerSource{} + err = c.client.Get(). + Namespace(c.ns). + Resource("containersources"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ContainerSources that match those selectors. +func (c *containerSources) List(opts v1.ListOptions) (result *v1alpha1.ContainerSourceList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ContainerSourceList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("containersources"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested containerSources. +func (c *containerSources) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("containersources"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a containerSource and creates it. Returns the server's representation of the containerSource, and an error, if there is any. +func (c *containerSources) Create(containerSource *v1alpha1.ContainerSource) (result *v1alpha1.ContainerSource, err error) { + result = &v1alpha1.ContainerSource{} + err = c.client.Post(). + Namespace(c.ns). + Resource("containersources"). + Body(containerSource). + Do(). + Into(result) + return +} + +// Update takes the representation of a containerSource and updates it. Returns the server's representation of the containerSource, and an error, if there is any. +func (c *containerSources) Update(containerSource *v1alpha1.ContainerSource) (result *v1alpha1.ContainerSource, err error) { + result = &v1alpha1.ContainerSource{} + err = c.client.Put(). + Namespace(c.ns). + Resource("containersources"). + Name(containerSource.Name). + Body(containerSource). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *containerSources) UpdateStatus(containerSource *v1alpha1.ContainerSource) (result *v1alpha1.ContainerSource, err error) { + result = &v1alpha1.ContainerSource{} + err = c.client.Put(). + Namespace(c.ns). + Resource("containersources"). + Name(containerSource.Name). + SubResource("status"). + Body(containerSource). + Do(). + Into(result) + return +} + +// Delete takes name of the containerSource and deletes it. Returns an error if one occurs. +func (c *containerSources) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("containersources"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *containerSources) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("containersources"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched containerSource. +func (c *containerSources) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ContainerSource, err error) { + result = &v1alpha1.ContainerSource{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("containersources"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/cronjobsource.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/cronjobsource.go new file mode 100644 index 0000000000..1f42256801 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/cronjobsource.go @@ -0,0 +1,191 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" + scheme "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +// CronJobSourcesGetter has a method to return a CronJobSourceInterface. +// A group's client should implement this interface. +type CronJobSourcesGetter interface { + CronJobSources(namespace string) CronJobSourceInterface +} + +// CronJobSourceInterface has methods to work with CronJobSource resources. +type CronJobSourceInterface interface { + Create(*v1alpha1.CronJobSource) (*v1alpha1.CronJobSource, error) + Update(*v1alpha1.CronJobSource) (*v1alpha1.CronJobSource, error) + UpdateStatus(*v1alpha1.CronJobSource) (*v1alpha1.CronJobSource, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.CronJobSource, error) + List(opts v1.ListOptions) (*v1alpha1.CronJobSourceList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.CronJobSource, err error) + CronJobSourceExpansion +} + +// cronJobSources implements CronJobSourceInterface +type cronJobSources struct { + client rest.Interface + ns string +} + +// newCronJobSources returns a CronJobSources +func newCronJobSources(c *SourcesV1alpha1Client, namespace string) *cronJobSources { + return &cronJobSources{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cronJobSource, and returns the corresponding cronJobSource object, and an error if there is any. +func (c *cronJobSources) Get(name string, options v1.GetOptions) (result *v1alpha1.CronJobSource, err error) { + result = &v1alpha1.CronJobSource{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cronjobsources"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CronJobSources that match those selectors. +func (c *cronJobSources) List(opts v1.ListOptions) (result *v1alpha1.CronJobSourceList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.CronJobSourceList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cronjobsources"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cronJobSources. +func (c *cronJobSources) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cronjobsources"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a cronJobSource and creates it. Returns the server's representation of the cronJobSource, and an error, if there is any. +func (c *cronJobSources) Create(cronJobSource *v1alpha1.CronJobSource) (result *v1alpha1.CronJobSource, err error) { + result = &v1alpha1.CronJobSource{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cronjobsources"). + Body(cronJobSource). + Do(). + Into(result) + return +} + +// Update takes the representation of a cronJobSource and updates it. Returns the server's representation of the cronJobSource, and an error, if there is any. +func (c *cronJobSources) Update(cronJobSource *v1alpha1.CronJobSource) (result *v1alpha1.CronJobSource, err error) { + result = &v1alpha1.CronJobSource{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cronjobsources"). + Name(cronJobSource.Name). + Body(cronJobSource). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *cronJobSources) UpdateStatus(cronJobSource *v1alpha1.CronJobSource) (result *v1alpha1.CronJobSource, err error) { + result = &v1alpha1.CronJobSource{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cronjobsources"). + Name(cronJobSource.Name). + SubResource("status"). + Body(cronJobSource). + Do(). + Into(result) + return +} + +// Delete takes name of the cronJobSource and deletes it. Returns an error if one occurs. +func (c *cronJobSources) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cronjobsources"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cronJobSources) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cronjobsources"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched cronJobSource. +func (c *cronJobSources) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.CronJobSource, err error) { + result = &v1alpha1.CronJobSource{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cronjobsources"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/doc.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/doc.go new file mode 100644 index 0000000000..a1c6bb9fe8 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/generated_expansion.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/generated_expansion.go new file mode 100644 index 0000000000..90d7d66818 --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/generated_expansion.go @@ -0,0 +1,25 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type ApiServerSourceExpansion interface{} + +type ContainerSourceExpansion interface{} + +type CronJobSourceExpansion interface{} diff --git a/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/sources_client.go b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/sources_client.go new file mode 100644 index 0000000000..ef2db2a47a --- /dev/null +++ b/vendor/knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1/sources_client.go @@ -0,0 +1,99 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + rest "k8s.io/client-go/rest" + v1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +type SourcesV1alpha1Interface interface { + RESTClient() rest.Interface + ApiServerSourcesGetter + ContainerSourcesGetter + CronJobSourcesGetter +} + +// SourcesV1alpha1Client is used to interact with features provided by the sources.eventing.knative.dev group. +type SourcesV1alpha1Client struct { + restClient rest.Interface +} + +func (c *SourcesV1alpha1Client) ApiServerSources(namespace string) ApiServerSourceInterface { + return newApiServerSources(c, namespace) +} + +func (c *SourcesV1alpha1Client) ContainerSources(namespace string) ContainerSourceInterface { + return newContainerSources(c, namespace) +} + +func (c *SourcesV1alpha1Client) CronJobSources(namespace string) CronJobSourceInterface { + return newCronJobSources(c, namespace) +} + +// NewForConfig creates a new SourcesV1alpha1Client for the given config. +func NewForConfig(c *rest.Config) (*SourcesV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &SourcesV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new SourcesV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *SourcesV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new SourcesV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *SourcesV1alpha1Client { + return &SourcesV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *SourcesV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/knative.dev/pkg/apis/duck/README.md b/vendor/knative.dev/pkg/apis/duck/README.md new file mode 100644 index 0000000000..a56e4c2d12 --- /dev/null +++ b/vendor/knative.dev/pkg/apis/duck/README.md @@ -0,0 +1,95 @@ +# Duck Types + +Knative leverages duck-typing to interact with resources inside of Kubernetes +without explicit knowlage of the full resource shape. `knative/pkg` defines two +duck types that are used throughout Knative: `Addressable` and `Source`. + +For APIs leveraging `ObjectReference`, the context of the resource in question +identifies the duck-type. To enable the case where no `ObjectRefrence` is used, +we have labeled the Custom Resource Definition with the duck-type. Those labels +are as follows: + +| Label | Duck-Type | +| ----------------------------------- | ----------------------------------------------------------------------------- | +| `duck.knative.dev/addressable=true` | [Addressable](https://godoc.org/knative.dev/pkg/apis/duck/v1#AddressableType) | +| `duck.knative.dev/source=true` | [Source](https://godoc.org/knative.dev/pkg/apis/duck/v1#Source) | + +## Addressable Shape + +Addressable is expected to be the following shape: + +```yaml +apiVersion: group/version +kind: Kind +status: + address: + url: http://host/path?query +``` + +## Source Shape + +Source is expected to be in the following shape: + +(with ref sink) + +```yaml +apiVersion: group/version +kind: Kind +spec: + sink: + ref: + apiVersion: group/version + kind: AnAddressableKind + name: a-name + ceOverrides: + extensions: + key: value +status: + observedGeneration: 1 + conditions: + - type: Ready + status: "True" + sinkUri: http://host +``` + +(with uri sink) + +```yaml +apiVersion: group/version +kind: Kind +spec: + sink: + uri: http://host/path?query + ceOverrides: + extensions: + key: value +status: + observedGeneration: 1 + conditions: + - type: Ready + status: "True" + sinkUri: http://host/path?query +``` + +(with ref and uri sink) + +```yaml +apiVersion: group/version +kind: Kind +spec: + sink: + ref: + apiVersion: group/version + kind: AnAddressableKind + name: a-name + uri: /path?query + ceOverrides: + extensions: + key: value +status: + observedGeneration: 1 + conditions: + - type: Ready + status: "True" + sinkUri: http://host/path?query +``` diff --git a/vendor/knative.dev/pkg/apis/v1alpha1/destination.go b/vendor/knative.dev/pkg/apis/v1alpha1/destination.go index dae152dec1..85c4eebfbe 100644 --- a/vendor/knative.dev/pkg/apis/v1alpha1/destination.go +++ b/vendor/knative.dev/pkg/apis/v1alpha1/destination.go @@ -18,6 +18,7 @@ package v1alpha1 import ( "context" + corev1 "k8s.io/api/core/v1" "knative.dev/pkg/apis" ) @@ -28,36 +29,119 @@ type Destination struct { // +optional Ref *corev1.ObjectReference `json:"ref,omitempty"` + // +optional + DeprecatedAPIVersion string `json:"apiVersion,omitempty"` + + // +optional + DeprecatedKind string `json:"kind,omitempty"` + + // +optional + DeprecatedName string `json:"name,omitempty"` + + // +optional + DeprecatedNamespace string `json:"namespace,omitempty"` + // URI can be an absolute URL(non-empty scheme and non-empty host) pointing to the target or a relative URI. Relative URIs will be resolved using the base URI retrieved from Ref. // +optional URI *apis.URL `json:"uri,omitempty"` } -func (current *Destination) Validate(ctx context.Context) *apis.FieldError { - if current != nil { - return ValidateDestination(*current).ViaField(apis.CurrentField) - } else { +func (dest *Destination) Validate(ctx context.Context) *apis.FieldError { + if dest == nil { return nil } + return ValidateDestination(*dest, true).ViaField(apis.CurrentField) } -func ValidateDestination(dest Destination) *apis.FieldError { - if dest.Ref == nil && dest.URI == nil { - return apis.ErrGeneric("expected at least one, got neither", "ref", "uri") +func (dest *Destination) ValidateDisallowDeprecated(ctx context.Context) *apis.FieldError { + if dest == nil { + return nil + } + return ValidateDestination(*dest, false).ViaField(apis.CurrentField) +} + +// ValidateDestination validates Destination and either allows or disallows +// Deprecated* fields depending on the flag. +func ValidateDestination(dest Destination, allowDeprecatedFields bool) *apis.FieldError { + if !allowDeprecatedFields { + var errs *apis.FieldError + if dest.DeprecatedAPIVersion != "" { + errs = errs.Also(apis.ErrInvalidValue("apiVersion is not allowed here, it's a deprecated value", "apiVersion")) + } + if dest.DeprecatedKind != "" { + errs = errs.Also(apis.ErrInvalidValue("kind is not allowed here, it's a deprecated value", "kind")) + } + if dest.DeprecatedName != "" { + errs = errs.Also(apis.ErrInvalidValue("name is not allowed here, it's a deprecated value", "name")) + } + if dest.DeprecatedNamespace != "" { + errs = errs.Also(apis.ErrInvalidValue("namespace is not allowed here, it's a deprecated value", "namespace")) + } + if errs != nil { + return errs + } + } + + deprecatedObjectReference := dest.deprecatedObjectReference() + if dest.Ref != nil && deprecatedObjectReference != nil { + return apis.ErrGeneric("Ref and [apiVersion, kind, name] can't be both present", "[apiVersion, kind, name]", "ref") + } + + var ref *corev1.ObjectReference + if dest.Ref != nil { + ref = dest.Ref + } else { + ref = deprecatedObjectReference } - if dest.Ref != nil && dest.URI != nil && dest.URI.URL().IsAbs() { - return apis.ErrGeneric("Absolute URI is not allowed when Ref is present", "ref", "uri") + if ref == nil && dest.URI == nil { + return apis.ErrGeneric("expected at least one, got none", "[apiVersion, kind, name]", "ref", "uri") + } + + if ref != nil && dest.URI != nil && dest.URI.URL().IsAbs() { + return apis.ErrGeneric("Absolute URI is not allowed when Ref or [apiVersion, kind, name] is present", "[apiVersion, kind, name]", "ref", "uri") } // IsAbs() check whether the URL has a non-empty scheme. Besides the non-empty scheme, we also require dest.URI has a non-empty host - if dest.Ref == nil && dest.URI != nil && (!dest.URI.URL().IsAbs() || dest.URI.Host == "") { - return apis.ErrInvalidValue("Relative URI is not allowed when Ref is absent", "uri") + if ref == nil && dest.URI != nil && (!dest.URI.URL().IsAbs() || dest.URI.Host == "") { + return apis.ErrInvalidValue("Relative URI is not allowed when Ref and [apiVersion, kind, name] is absent", "uri") + } + if ref != nil && dest.URI == nil { + if dest.Ref != nil { + return validateDestinationRef(*ref).ViaField("ref") + } else { + return validateDestinationRef(*ref) } - if dest.Ref != nil && dest.URI == nil{ - return validateDestinationRef(*dest.Ref).ViaField("ref") } return nil } +func (dest Destination) deprecatedObjectReference() *corev1.ObjectReference { + if dest.DeprecatedAPIVersion == "" && dest.DeprecatedKind == "" && dest.DeprecatedName == "" && dest.DeprecatedNamespace == "" { + return nil + } + return &corev1.ObjectReference{ + Kind: dest.DeprecatedKind, + APIVersion: dest.DeprecatedAPIVersion, + Name: dest.DeprecatedName, + Namespace: dest.DeprecatedNamespace, + } +} + +// GetRef gets the ObjectReference from this Destination, if one is present. If no ref is present, +// then nil is returned. +// Note: this mostly exists to abstract away the deprecated ObjectReference fields. Once they are +// removed, then this method should probably be removed too. +func (dest *Destination) GetRef() *corev1.ObjectReference { + if dest == nil { + return nil + } + if dest.Ref != nil { + return dest.Ref + } + if ref := dest.deprecatedObjectReference(); ref != nil { + return ref + } + return nil +} func validateDestinationRef(ref corev1.ObjectReference) *apis.FieldError { // Check the object. diff --git a/vendor/knative.dev/pkg/metrics/config.go b/vendor/knative.dev/pkg/metrics/config.go index 3e3d922f5b..af7e3e7299 100644 --- a/vendor/knative.dev/pkg/metrics/config.go +++ b/vendor/knative.dev/pkg/metrics/config.go @@ -44,8 +44,13 @@ const ( AllowStackdriverCustomMetricsKey = "metrics.allow-stackdriver-custom-metrics" BackendDestinationKey = "metrics.backend-destination" ReportingPeriodKey = "metrics.reporting-period-seconds" - StackdriverProjectIDKey = "metrics.stackdriver-project-id" StackdriverCustomMetricSubDomainKey = "metrics.stackdriver-custom-metrics-subdomain" + // Stackdriver client configuration keys + stackdriverProjectIDKey = "metrics.stackdriver-project-id" + stackdriverGCPLocationKey = "metrics.stackdriver-gcp-location" + stackdriverClusterNameKey = "metrics.stackdriver-cluster-name" + stackdriverGCPSecretNameKey = "metrics.stackdriver-gcp-secret-name" + stackdriverGCPSecretNamespaceKey = "metrics.stackdriver-gcp-secret-namespace" // Stackdriver is used for Stackdriver backend Stackdriver metricsBackend = "stackdriver" @@ -76,9 +81,6 @@ type metricsConfig struct { prometheusPort int // ---- Stackdriver specific below ---- - // stackdriverProjectID is the stackdriver project ID where the stats data are - // uploaded to. This is not the GCP project ID. - stackdriverProjectID string // allowStackdriverCustomMetrics indicates whether it is allowed to send metrics to // Stackdriver using "global" resource type and custom metric type if the // metrics are not supported by the registered monitored resource types. Setting this @@ -100,6 +102,42 @@ type metricsConfig struct { // E.g., "custom.googleapis.com//". // Store this in a variable to reduce string join operations. stackdriverCustomMetricTypePrefix string + // stackdriverClientConfig is the metadata to configure the metrics exporter's Stackdriver client. + stackdriverClientConfig stackdriverClientConfig +} + +// stackdriverClientConfig encapsulates the metadata required to configure a Stackdriver client. +type stackdriverClientConfig struct { + // ProjectID is the stackdriver project ID to which data is uploaded. + // This is not necessarily the GCP project ID where the Kubernetes cluster is hosted. + // Required when the Kubernetes cluster is not hosted on GCE. + ProjectID string + // GCPLocation is the GCP region or zone to which data is uploaded. + // This is not necessarily the GCP location where the Kubernetes cluster is hosted. + // Required when the Kubernetes cluster is not hosted on GCE. + GCPLocation string + // ClusterName is the cluster name with which the data will be associated in Stackdriver. + // Required when the Kubernetes cluster is not hosted on GCE. + ClusterName string + // GCPSecretName is the optional GCP service account key which will be used to + // authenticate with Stackdriver. If not provided, Google Application Default Credentials + // will be used (https://cloud.google.com/docs/authentication/production). + GCPSecretName string + // GCPSecretNamespace is the Kubernetes namespace where GCPSecretName is located. + // The Kubernetes ServiceAccount used by the pod that is exporting data to + // Stackdriver should have access to Secrets in this namespace. + GCPSecretNamespace string +} + +// newStackdriverClientConfigFromMap creates a stackdriverClientConfig from the given map +func newStackdriverClientConfigFromMap(config map[string]string) *stackdriverClientConfig { + return &stackdriverClientConfig{ + ProjectID: config[stackdriverProjectIDKey], + GCPLocation: config[stackdriverGCPLocationKey], + ClusterName: config[stackdriverClusterNameKey], + GCPSecretName: config[stackdriverGCPSecretNameKey], + GCPSecretNamespace: config[stackdriverGCPSecretNamespaceKey], + } } func createMetricsConfig(ops ExporterOptions, logger *zap.SugaredLogger) (*metricsConfig, error) { @@ -148,11 +186,12 @@ func createMetricsConfig(ops ExporterOptions, logger *zap.SugaredLogger) (*metri mc.prometheusPort = pp } - // If stackdriverProjectIDKey is not provided for stackdriver backend destination, OpenCensus will try to + // If stackdriverClientConfig is not provided for stackdriver backend destination, OpenCensus will try to // use the application default credentials. If that is not available, Opencensus would fail to create the // metrics exporter. if mc.backendDestination == Stackdriver { - mc.stackdriverProjectID = m[StackdriverProjectIDKey] + scc := newStackdriverClientConfigFromMap(m) + mc.stackdriverClientConfig = *scc mc.isStackdriverBackend = true mc.stackdriverMetricTypePrefix = path.Join(mc.domain, mc.component) diff --git a/vendor/knative.dev/pkg/metrics/exporter.go b/vendor/knative.dev/pkg/metrics/exporter.go index 22cebecf82..ddbb6b7d14 100644 --- a/vendor/knative.dev/pkg/metrics/exporter.go +++ b/vendor/knative.dev/pkg/metrics/exporter.go @@ -79,12 +79,9 @@ func UpdateExporterFromConfigMap(component string, logger *zap.SugaredLogger) fu // to prevent a race condition between reading the current configuration // and updating the current exporter. func UpdateExporter(ops ExporterOptions, logger *zap.SugaredLogger) error { - metricsMux.Lock() - defer metricsMux.Unlock() - newConfig, err := createMetricsConfig(ops, logger) if err != nil { - if curMetricsExporter == nil { + if getCurMetricsConfig() == nil { // Fail the process if there doesn't exist an exporter. logger.Errorw("Failed to get a valid metrics config", zap.Error(err)) } else { @@ -95,18 +92,18 @@ func UpdateExporter(ops ExporterOptions, logger *zap.SugaredLogger) error { if isNewExporterRequired(newConfig) { logger.Info("Flushing the existing exporter before setting up the new exporter.") - flushExporterUnlocked(curMetricsExporter) + FlushExporter() e, err := newMetricsExporter(newConfig, logger) if err != nil { logger.Errorf("Failed to update a new metrics exporter based on metric config %v. error: %v", newConfig, err) return err } - existingConfig := curMetricsConfig - setCurMetricsExporterUnlocked(e) + existingConfig := getCurMetricsConfig() + setCurMetricsExporter(e) logger.Infof("Successfully updated the metrics exporter; old config: %v; new config %v", existingConfig, newConfig) } - setCurMetricsConfigUnlocked(newConfig) + setCurMetricsConfig(newConfig) return nil } @@ -114,18 +111,18 @@ func UpdateExporter(ops ExporterOptions, logger *zap.SugaredLogger) error { // or stackdriver project ID changes for stackdriver backend, we need to update the metrics exporter. // This function is not implicitly thread-safe. func isNewExporterRequired(newConfig *metricsConfig) bool { - cc := curMetricsConfig + cc := getCurMetricsConfig() if cc == nil || newConfig.backendDestination != cc.backendDestination { return true } - return newConfig.backendDestination == Stackdriver && newConfig.stackdriverProjectID != cc.stackdriverProjectID + return newConfig.backendDestination == Stackdriver && newConfig.stackdriverClientConfig != cc.stackdriverClientConfig } // newMetricsExporter gets a metrics exporter based on the config. // This function is not implicitly thread-safe. func newMetricsExporter(config *metricsConfig, logger *zap.SugaredLogger) (view.Exporter, error) { - ce := curMetricsExporter + ce := getCurMetricsExporter() // If there is a Prometheus Exporter server running, stop it. resetCurPromSrv() @@ -159,10 +156,6 @@ func getCurMetricsExporter() view.Exporter { func setCurMetricsExporter(e view.Exporter) { metricsMux.Lock() defer metricsMux.Unlock() - setCurMetricsExporterUnlocked(e) -} - -func setCurMetricsExporterUnlocked(e view.Exporter) { view.RegisterExporter(e) curMetricsExporter = e } @@ -176,10 +169,6 @@ func getCurMetricsConfig() *metricsConfig { func setCurMetricsConfig(c *metricsConfig) { metricsMux.Lock() defer metricsMux.Unlock() - setCurMetricsConfigUnlocked(c) -} - -func setCurMetricsConfigUnlocked(c *metricsConfig) { if c != nil { view.SetReportingPeriod(c.reportingPeriod) } else { @@ -194,10 +183,6 @@ func setCurMetricsConfigUnlocked(c *metricsConfig) { // Return value indicates whether the exporter is flushable or not. func FlushExporter() bool { e := getCurMetricsExporter() - return flushExporterUnlocked(e) -} - -func flushExporterUnlocked(e view.Exporter) bool { if e == nil { return false } diff --git a/vendor/knative.dev/pkg/metrics/gcp_metadata.go b/vendor/knative.dev/pkg/metrics/gcp_metadata.go index 9cf9882e24..ec6ae878e3 100644 --- a/vendor/knative.dev/pkg/metrics/gcp_metadata.go +++ b/vendor/knative.dev/pkg/metrics/gcp_metadata.go @@ -33,17 +33,21 @@ func retrieveGCPMetadata() *gcpMetadata { location: metricskey.ValueUnknown, cluster: metricskey.ValueUnknown, } - project, err := metadata.NumericProjectID() - if err == nil && project != "" { - gm.project = project - } - location, err := metadata.InstanceAttributeValue("cluster-location") - if err == nil && location != "" { - gm.location = location - } - cluster, err := metadata.InstanceAttributeValue("cluster-name") - if err == nil && cluster != "" { - gm.cluster = cluster + + if metadata.OnGCE() { + project, err := metadata.NumericProjectID() + if err == nil && project != "" { + gm.project = project + } + location, err := metadata.InstanceAttributeValue("cluster-location") + if err == nil && location != "" { + gm.location = location + } + cluster, err := metadata.InstanceAttributeValue("cluster-name") + if err == nil && cluster != "" { + gm.cluster = cluster + } } + return &gm } diff --git a/vendor/knative.dev/pkg/metrics/metricskey/constants_serving.go b/vendor/knative.dev/pkg/metrics/metricskey/constants_serving.go index 2b50dda770..d9fc0a3496 100644 --- a/vendor/knative.dev/pkg/metrics/metricskey/constants_serving.go +++ b/vendor/knative.dev/pkg/metrics/metricskey/constants_serving.go @@ -53,8 +53,8 @@ var ( // KnativeRevisionMetrics stores a set of metric types which are supported // by resource type knative_revision. KnativeRevisionMetrics = sets.NewString( - "knative.dev/serving/activator/request_count", - "knative.dev/serving/activator/request_latencies", + "knative.dev/internal/serving/activator/request_count", + "knative.dev/internal/serving/activator/request_latencies", "knative.dev/serving/autoscaler/desired_pods", "knative.dev/serving/autoscaler/requested_pods", "knative.dev/serving/autoscaler/actual_pods", @@ -62,7 +62,7 @@ var ( "knative.dev/serving/autoscaler/panic_request_concurrency", "knative.dev/serving/autoscaler/target_concurrency_per_pod", "knative.dev/serving/autoscaler/panic_mode", - "knative.dev/serving/revision/request_count", - "knative.dev/serving/revision/request_latencies", + "knative.dev/internal/serving/revision/request_count", + "knative.dev/internal/serving/revision/request_latencies", ) ) diff --git a/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go b/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go index 2684bf3e26..bb396ac0c6 100644 --- a/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go +++ b/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go @@ -17,14 +17,22 @@ limitations under the License. package metrics import ( + "fmt" "path" + "sync" "contrib.go.opencensus.io/exporter/stackdriver" "contrib.go.opencensus.io/exporter/stackdriver/monitoredresource" "go.opencensus.io/stats/view" "go.opencensus.io/tag" "go.uber.org/zap" + "google.golang.org/api/option" "knative.dev/pkg/metrics/metricskey" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" ) const ( @@ -32,28 +40,23 @@ const ( // defaultCustomMetricSubDomain is the default subdomain to use for unsupported metrics by monitored resource types. // See: https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.metricDescriptors#MetricDescriptor defaultCustomMetricSubDomain = "knative.dev" + // secretNamespaceDefault is the namespace to search for a k8s Secret to pass to Stackdriver client to authenticate with Stackdriver. + secretNamespaceDefault = "default" + // secretDataFieldKey is the name of the k8s Secret field that contains the Secret's key. + secretDataFieldKey = "key.json" ) var ( - // gcpMetadataFunc is the function used to fetch GCP metadata. - // In product usage, this is always set to function retrieveGCPMetadata. - // In unit tests this is set to a fake one to avoid calling GCP metadata - // service. - gcpMetadataFunc func() *gcpMetadata - - // newStackdriverExporterFunc is the function used to create new stackdriver - // exporter. - // In product usage, this is always set to function newOpencensusSDExporter. - // In unit tests this is set to a fake one to avoid calling actual Google API - // service. - newStackdriverExporterFunc func(stackdriver.Options) (view.Exporter, error) + // kubeclient is the in-cluster Kubernetes kubeclient, which is lazy-initialized on first use. + kubeclient *kubernetes.Clientset + // initClientOnce is the lazy initializer for kubeclient. + initClientOnce sync.Once + // kubeclientInitErr capture an error during initClientOnce + kubeclientInitErr error ) func init() { - // Set gcpMetadataFunc to call GCP metadata service. - gcpMetadataFunc = retrieveGCPMetadata - - newStackdriverExporterFunc = newOpencensusSDExporter + kubeclientInitErr = nil } func newOpencensusSDExporter(o stackdriver.Options) (view.Exporter, error) { @@ -63,10 +66,18 @@ func newOpencensusSDExporter(o stackdriver.Options) (view.Exporter, error) { // TODO should be properly refactored to be able to inject the getMonitoredResourceFunc function. // See https://github.com/knative/pkg/issues/608 func newStackdriverExporter(config *metricsConfig, logger *zap.SugaredLogger) (view.Exporter, error) { - gm := gcpMetadataFunc() + gm := getMergedGCPMetadata(config) mtf := getMetricTypeFunc(config.stackdriverMetricTypePrefix, config.stackdriverCustomMetricTypePrefix) - e, err := newStackdriverExporterFunc(stackdriver.Options{ - ProjectID: config.stackdriverProjectID, + co, err := getStackdriverExporterClientOptions(&config.stackdriverClientConfig) + if err != nil { + logger.Warnw("Issue configuring Stackdriver exporter client options, no additional client options will be used: ", zap.Error(err)) + } + // Automatically fall back on Google application default credentials + e, err := newOpencensusSDExporter(stackdriver.Options{ + ProjectID: gm.project, + Location: gm.location, + MonitoringClientOptions: co, + TraceClientOptions: co, GetMetricDisplayName: mtf, // Use metric type for display name for custom metrics. No impact on built-in metrics. GetMetricType: mtf, GetMonitoredResource: getMonitoredResourceFunc(config.stackdriverMetricTypePrefix, gm), @@ -80,6 +91,42 @@ func newStackdriverExporter(config *metricsConfig, logger *zap.SugaredLogger) (v return e, nil } +// getStackdriverExporterClientOptions creates client options for the opencensus Stackdriver exporter from the given stackdriverClientConfig. +// On error, an empty array of client options is returned. +func getStackdriverExporterClientOptions(sdconfig *stackdriverClientConfig) ([]option.ClientOption, error) { + var co []option.ClientOption + if sdconfig.GCPSecretName != "" { + secret, err := getStackdriverSecret(sdconfig) + if err != nil { + return co, err + } + + co = append(co, convertSecretToExporterOption(secret)) + } + + return co, nil +} + +// getMergedGCPMetadata returns GCP metadata required to export metrics +// to Stackdriver. Values can come from the GCE metadata server or the config. +// Values explicitly set in the config take the highest precedent. +func getMergedGCPMetadata(config *metricsConfig) *gcpMetadata { + gm := retrieveGCPMetadata() + if config.stackdriverClientConfig.ProjectID != "" { + gm.project = config.stackdriverClientConfig.ProjectID + } + + if config.stackdriverClientConfig.GCPLocation != "" { + gm.location = config.stackdriverClientConfig.GCPLocation + } + + if config.stackdriverClientConfig.ClusterName != "" { + gm.cluster = config.stackdriverClientConfig.ClusterName + } + + return gm +} + func getMonitoredResourceFunc(metricTypePrefix string, gm *gcpMetadata) func(v *view.View, tags []tag.Tag) ([]tag.Tag, monitoredresource.Interface) { return func(view *view.View, tags []tag.Tag) ([]tag.Tag, monitoredresource.Interface) { metricType := path.Join(metricTypePrefix, view.Measure.Name()) @@ -115,3 +162,49 @@ func getMetricTypeFunc(metricTypePrefix, customMetricTypePrefix string) func(vie return path.Join(customMetricTypePrefix, view.Measure.Name()) } } + +// getStackdriverSecret returns the Kubernetes Secret specified in the given config. +func getStackdriverSecret(sdconfig *stackdriverClientConfig) (*corev1.Secret, error) { + if err := ensureKubeclient(); err != nil { + return nil, err + } + + ns := sdconfig.GCPSecretNamespace + if ns == "" { + ns = secretNamespaceDefault + } + + sec, secErr := kubeclient.CoreV1().Secrets(ns).Get(sdconfig.GCPSecretName, metav1.GetOptions{}) + + if secErr != nil { + return nil, fmt.Errorf("Error getting Secret [%v] in namespace [%v]: %v", sdconfig.GCPSecretName, sdconfig.GCPSecretNamespace, secErr) + } + + return sec, nil +} + +// convertSecretToExporterOption converts a Kubernetes Secret to an OpenCensus Stackdriver Exporter Option. +func convertSecretToExporterOption(secret *corev1.Secret) option.ClientOption { + return option.WithCredentialsJSON(secret.Data[secretDataFieldKey]) +} + +// ensureKubeclient is the lazy initializer for kubeclient. +func ensureKubeclient() error { + // initClientOnce is only run once and cannot return error, so kubeclientInitErr is used to capture errors. + initClientOnce.Do(func() { + config, err := rest.InClusterConfig() + if err != nil { + kubeclientInitErr = err + return + } + + cs, err := kubernetes.NewForConfig(config) + if err != nil { + kubeclientInitErr = err + return + } + kubeclient = cs + }) + + return kubeclientInitErr +} diff --git a/vendor/knative.dev/pkg/webhook/OWNERS b/vendor/knative.dev/pkg/webhook/OWNERS new file mode 100644 index 0000000000..b87878d94a --- /dev/null +++ b/vendor/knative.dev/pkg/webhook/OWNERS @@ -0,0 +1,4 @@ +# The OWNERS file is used by prow to automatically merge approved PRs. + +approvers: +- webhook-approvers diff --git a/vendor/knative.dev/pkg/webhook/certs.go b/vendor/knative.dev/pkg/webhook/certs.go new file mode 100644 index 0000000000..1a0348394d --- /dev/null +++ b/vendor/knative.dev/pkg/webhook/certs.go @@ -0,0 +1,165 @@ +/* +Copyright 2018 The Knative 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 ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "errors" + "math/big" + "time" + + "go.uber.org/zap" + + "knative.dev/pkg/logging" +) + +const ( + organization = "knative.dev" +) + +// Create the common parts of the cert. These don't change between +// the root/CA cert and the server cert. +func createCertTemplate(name, namespace string) (*x509.Certificate, error) { + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + return nil, errors.New("failed to generate serial number: " + err.Error()) + } + + serviceName := name + "." + namespace + serviceNames := []string{ + name, + serviceName, + serviceName + ".svc", + serviceName + ".svc.cluster.local", + } + + tmpl := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{Organization: []string{organization}}, + SignatureAlgorithm: x509.SHA256WithRSA, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(1, 0, 0), // valid for 1 years + BasicConstraintsValid: true, + DNSNames: serviceNames, + } + return &tmpl, nil +} + +// Create cert template suitable for CA and hence signing +func createCACertTemplate(name, namespace string) (*x509.Certificate, error) { + rootCert, err := createCertTemplate(name, namespace) + if err != nil { + return nil, err + } + // Make it into a CA cert and change it so we can use it to sign certs + rootCert.IsCA = true + rootCert.KeyUsage = x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature + rootCert.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth} + return rootCert, nil +} + +// Create cert template that we can use on the server for TLS +func createServerCertTemplate(name, namespace string) (*x509.Certificate, error) { + serverCert, err := createCertTemplate(name, namespace) + if err != nil { + return nil, err + } + serverCert.KeyUsage = x509.KeyUsageDigitalSignature + serverCert.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} + return serverCert, err +} + +// Actually sign the cert and return things in a form that we can use later on +func createCert(template, parent *x509.Certificate, pub interface{}, parentPriv interface{}) ( + cert *x509.Certificate, certPEM []byte, err error) { + + certDER, err := x509.CreateCertificate(rand.Reader, template, parent, pub, parentPriv) + if err != nil { + return + } + cert, err = x509.ParseCertificate(certDER) + if err != nil { + return + } + b := pem.Block{Type: "CERTIFICATE", Bytes: certDER} + certPEM = pem.EncodeToMemory(&b) + return +} + +func createCA(ctx context.Context, name, namespace string) (*rsa.PrivateKey, *x509.Certificate, []byte, error) { + logger := logging.FromContext(ctx) + rootKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + logger.Errorw("error generating random key", zap.Error(err)) + return nil, nil, nil, err + } + + rootCertTmpl, err := createCACertTemplate(name, namespace) + if err != nil { + logger.Errorw("error generating CA cert", zap.Error(err)) + return nil, nil, nil, err + } + + rootCert, rootCertPEM, err := createCert(rootCertTmpl, rootCertTmpl, &rootKey.PublicKey, rootKey) + if err != nil { + logger.Errorw("error signing the CA cert", zap.Error(err)) + return nil, nil, nil, err + } + return rootKey, rootCert, rootCertPEM, nil +} + +// CreateCerts creates and returns a CA certificate and certificate and +// key for the server. serverKey and serverCert are used by the server +// to establish trust for clients, CA certificate is used by the +// client to verify the server authentication chain. +func CreateCerts(ctx context.Context, name, namespace string) (serverKey, serverCert, caCert []byte, err error) { + logger := logging.FromContext(ctx) + // First create a CA certificate and private key + caKey, caCertificate, caCertificatePEM, err := createCA(ctx, name, namespace) + if err != nil { + return nil, nil, nil, err + } + + // Then create the private key for the serving cert + servKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + logger.Errorw("error generating random key", zap.Error(err)) + return nil, nil, nil, err + } + servCertTemplate, err := createServerCertTemplate(name, namespace) + if err != nil { + logger.Errorw("failed to create the server certificate template", zap.Error(err)) + return nil, nil, nil, err + } + + // create a certificate which wraps the server's public key, sign it with the CA private key + _, servCertPEM, err := createCert(servCertTemplate, caCertificate, &servKey.PublicKey, caKey) + if err != nil { + logger.Errorw("error signing server certificate template", zap.Error(err)) + return nil, nil, nil, err + } + servKeyPEM := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(servKey), + }) + return servKeyPEM, servCertPEM, caCertificatePEM, nil +} diff --git a/vendor/knative.dev/pkg/webhook/config_validation_controller.go b/vendor/knative.dev/pkg/webhook/config_validation_controller.go new file mode 100644 index 0000000000..1f00f985b0 --- /dev/null +++ b/vendor/knative.dev/pkg/webhook/config_validation_controller.go @@ -0,0 +1,184 @@ +/* +Copyright 2019 The Knative 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 ( + "bytes" + "context" + "encoding/json" + "fmt" + "reflect" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" + + "knative.dev/pkg/configmap" + "knative.dev/pkg/kmp" + "knative.dev/pkg/logging" + "knative.dev/pkg/ptr" +) + +// ConfigValidationController implements the AdmissionController for ConfigMaps +type ConfigValidationController struct { + constructors map[string]reflect.Value + options ControllerOptions +} + +// NewConfigValidationController constructs a ConfigValidationController +func NewConfigValidationController( + constructors configmap.Constructors, + opts ControllerOptions) AdmissionController { + cfgValidations := &ConfigValidationController{ + constructors: make(map[string]reflect.Value), + options: opts, + } + + for configName, constructor := range constructors { + cfgValidations.registerConfig(configName, constructor) + } + + return cfgValidations +} + +func (ac *ConfigValidationController) Admit(ctx context.Context, request *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { + logger := logging.FromContext(ctx) + switch request.Operation { + case admissionv1beta1.Create, admissionv1beta1.Update: + default: + logger.Infof("Unhandled webhook operation, letting it through %v", request.Operation) + return &admissionv1beta1.AdmissionResponse{Allowed: true} + } + + if err := ac.validate(ctx, request); err != nil { + return makeErrorStatus("validation failed: %v", err) + } + + return &admissionv1beta1.AdmissionResponse{ + Allowed: true, + } +} + +func (ac *ConfigValidationController) Register(ctx context.Context, kubeClient kubernetes.Interface, caCert []byte) error { + client := kubeClient.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations() + logger := logging.FromContext(ctx) + + ruleScope := admissionregistrationv1beta1.NamespacedScope + rules := []admissionregistrationv1beta1.RuleWithOperations{{ + Operations: []admissionregistrationv1beta1.OperationType{ + admissionregistrationv1beta1.Create, + admissionregistrationv1beta1.Update, + }, + Rule: admissionregistrationv1beta1.Rule{ + APIGroups: []string{""}, + APIVersions: []string{"v1"}, + Resources: []string{"configmaps/*"}, + Scope: &ruleScope, + }, + }} + + configuredWebhook, err := client.Get(ac.options.ConfigValidationWebhookName, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("error retrieving webhook: %v", err) + } + + webhook := configuredWebhook.DeepCopy() + + // Clear out any previous (bad) OwnerReferences. + // See: https://github.com/knative/serving/issues/5845 + webhook.OwnerReferences = nil + + for i, wh := range webhook.Webhooks { + if wh.Name != webhook.Name { + continue + } + webhook.Webhooks[i].Rules = rules + webhook.Webhooks[i].ClientConfig.CABundle = caCert + if webhook.Webhooks[i].ClientConfig.Service == nil { + return fmt.Errorf("missing service reference for webhook: %s", wh.Name) + } + webhook.Webhooks[i].ClientConfig.Service.Path = ptr.String(ac.options.ConfigValidationControllerPath) + } + + if ok, err := kmp.SafeEqual(configuredWebhook, webhook); err != nil { + return fmt.Errorf("error diffing webhooks: %v", err) + } else if !ok { + logger.Info("Updating webhook") + if _, err := client.Update(webhook); err != nil { + return fmt.Errorf("failed to update webhook: %v", err) + } + } else { + logger.Info("Webhook is valid") + } + + return nil +} + +func (ac *ConfigValidationController) validate(ctx context.Context, req *admissionv1beta1.AdmissionRequest) error { + logger := logging.FromContext(ctx) + kind := req.Kind + newBytes := req.Object.Raw + + // Why, oh why are these different types... + gvk := schema.GroupVersionKind{ + Group: kind.Group, + Version: kind.Version, + Kind: kind.Kind, + } + + resourceGVK := corev1.SchemeGroupVersion.WithKind("ConfigMap") + if gvk != resourceGVK { + logger.Errorf("Unhandled kind: %v", gvk) + return fmt.Errorf("unhandled kind: %v", gvk) + } + + var newObj corev1.ConfigMap + if len(newBytes) != 0 { + newDecoder := json.NewDecoder(bytes.NewBuffer(newBytes)) + if err := newDecoder.Decode(&newObj); err != nil { + return fmt.Errorf("cannot decode incoming new object: %v", err) + } + } + + var err error + if constructor, ok := ac.constructors[newObj.Name]; ok { + + inputs := []reflect.Value{ + reflect.ValueOf(&newObj), + } + + outputs := constructor.Call(inputs) + errVal := outputs[1] + + if !errVal.IsNil() { + err = errVal.Interface().(error) + } + } + + return err +} + +func (ac *ConfigValidationController) registerConfig(name string, constructor interface{}) { + if err := configmap.ValidateConstructor(constructor); err != nil { + panic(err) + } + + ac.constructors[name] = reflect.ValueOf(constructor) +} diff --git a/vendor/knative.dev/pkg/webhook/resource_admission_controller.go b/vendor/knative.dev/pkg/webhook/resource_admission_controller.go new file mode 100644 index 0000000000..8dacc142ed --- /dev/null +++ b/vendor/knative.dev/pkg/webhook/resource_admission_controller.go @@ -0,0 +1,357 @@ +/* +Copyright 2019 The Knative 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 ( + "bytes" + "context" + "encoding/json" + "fmt" + "sort" + "strings" + + "github.com/markbates/inflect" + "github.com/mattbaird/jsonpatch" + "go.uber.org/zap" + admissionv1beta1 "k8s.io/api/admission/v1beta1" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" + + "knative.dev/pkg/apis" + "knative.dev/pkg/apis/duck" + "knative.dev/pkg/kmp" + "knative.dev/pkg/logging" + "knative.dev/pkg/ptr" +) + +// ResourceCallback defines a signature for resource specific (Route, Configuration, etc.) +// handlers that can validate and mutate an object. If non-nil error is returned, object mutation +// is denied. Mutations should be appended to the patches operations. +type ResourceCallback func(patches *[]jsonpatch.JsonPatchOperation, old GenericCRD, new GenericCRD) error + +// ResourceDefaulter defines a signature for resource specific (Route, Configuration, etc.) +// handlers that can set defaults on an object. If non-nil error is returned, object mutation +// is denied. Mutations should be appended to the patches operations. +type ResourceDefaulter func(patches *[]jsonpatch.JsonPatchOperation, crd GenericCRD) error + +// GenericCRD is the interface definition that allows us to perform the generic +// CRD actions like deciding whether to increment generation and so forth. +type GenericCRD interface { + apis.Defaultable + apis.Validatable + runtime.Object +} + +// ResourceAdmissionController implements the AdmissionController for resources +type ResourceAdmissionController struct { + handlers map[schema.GroupVersionKind]GenericCRD + options ControllerOptions + + disallowUnknownFields bool +} + +// NewResourceAdmissionController constructs a ResourceAdmissionController +func NewResourceAdmissionController( + handlers map[schema.GroupVersionKind]GenericCRD, + opts ControllerOptions, + disallowUnknownFields bool) AdmissionController { + return &ResourceAdmissionController{ + handlers: handlers, + options: opts, + disallowUnknownFields: disallowUnknownFields, + } +} + +func (ac *ResourceAdmissionController) Admit(ctx context.Context, request *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { + logger := logging.FromContext(ctx) + switch request.Operation { + case admissionv1beta1.Create, admissionv1beta1.Update: + default: + logger.Infof("Unhandled webhook operation, letting it through %v", request.Operation) + return &admissionv1beta1.AdmissionResponse{Allowed: true} + } + + patchBytes, err := ac.mutate(ctx, request) + if err != nil { + return makeErrorStatus("mutation failed: %v", err) + } + logger.Infof("Kind: %q PatchBytes: %v", request.Kind, string(patchBytes)) + + return &admissionv1beta1.AdmissionResponse{ + Patch: patchBytes, + Allowed: true, + PatchType: func() *admissionv1beta1.PatchType { + pt := admissionv1beta1.PatchTypeJSONPatch + return &pt + }(), + } +} + +func (ac *ResourceAdmissionController) Register(ctx context.Context, kubeClient kubernetes.Interface, caCert []byte) error { + client := kubeClient.AdmissionregistrationV1beta1().MutatingWebhookConfigurations() + logger := logging.FromContext(ctx) + + var rules []admissionregistrationv1beta1.RuleWithOperations + for gvk := range ac.handlers { + plural := strings.ToLower(inflect.Pluralize(gvk.Kind)) + + rules = append(rules, admissionregistrationv1beta1.RuleWithOperations{ + Operations: []admissionregistrationv1beta1.OperationType{ + admissionregistrationv1beta1.Create, + admissionregistrationv1beta1.Update, + }, + Rule: admissionregistrationv1beta1.Rule{ + APIGroups: []string{gvk.Group}, + APIVersions: []string{gvk.Version}, + Resources: []string{plural + "/*"}, + }, + }) + } + + // Sort the rules by Group, Version, Kind so that things are deterministically ordered. + sort.Slice(rules, func(i, j int) bool { + lhs, rhs := rules[i], rules[j] + if lhs.APIGroups[0] != rhs.APIGroups[0] { + return lhs.APIGroups[0] < rhs.APIGroups[0] + } + if lhs.APIVersions[0] != rhs.APIVersions[0] { + return lhs.APIVersions[0] < rhs.APIVersions[0] + } + return lhs.Resources[0] < rhs.Resources[0] + }) + + configuredWebhook, err := client.Get(ac.options.ResourceMutatingWebhookName, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("error retrieving webhook: %v", err) + } + + webhook := configuredWebhook.DeepCopy() + + // Clear out any previous (bad) OwnerReferences. + // See: https://github.com/knative/serving/issues/5845 + webhook.OwnerReferences = nil + + for i, wh := range webhook.Webhooks { + if wh.Name != webhook.Name { + continue + } + webhook.Webhooks[i].Rules = rules + webhook.Webhooks[i].ClientConfig.CABundle = caCert + if webhook.Webhooks[i].ClientConfig.Service == nil { + return fmt.Errorf("missing service reference for webhook: %s", wh.Name) + } + webhook.Webhooks[i].ClientConfig.Service.Path = ptr.String( + ac.options.ResourceAdmissionControllerPath) + } + + if ok, err := kmp.SafeEqual(configuredWebhook, webhook); err != nil { + return fmt.Errorf("error diffing webhooks: %v", err) + } else if !ok { + logger.Info("Updating webhook") + if _, err := client.Update(webhook); err != nil { + return fmt.Errorf("failed to update webhook: %v", err) + } + } else { + logger.Info("Webhook is valid") + } + return nil +} + +func (ac *ResourceAdmissionController) mutate(ctx context.Context, req *admissionv1beta1.AdmissionRequest) ([]byte, error) { + kind := req.Kind + newBytes := req.Object.Raw + oldBytes := req.OldObject.Raw + // Why, oh why are these different types... + gvk := schema.GroupVersionKind{ + Group: kind.Group, + Version: kind.Version, + Kind: kind.Kind, + } + + logger := logging.FromContext(ctx) + handler, ok := ac.handlers[gvk] + if !ok { + logger.Errorf("Unhandled kind: %v", gvk) + return nil, fmt.Errorf("unhandled kind: %v", gvk) + } + + // nil values denote absence of `old` (create) or `new` (delete) objects. + var oldObj, newObj GenericCRD + + if len(newBytes) != 0 { + newObj = handler.DeepCopyObject().(GenericCRD) + newDecoder := json.NewDecoder(bytes.NewBuffer(newBytes)) + if ac.disallowUnknownFields { + newDecoder.DisallowUnknownFields() + } + if err := newDecoder.Decode(&newObj); err != nil { + return nil, fmt.Errorf("cannot decode incoming new object: %v", err) + } + } + if len(oldBytes) != 0 { + oldObj = handler.DeepCopyObject().(GenericCRD) + oldDecoder := json.NewDecoder(bytes.NewBuffer(oldBytes)) + if ac.disallowUnknownFields { + oldDecoder.DisallowUnknownFields() + } + if err := oldDecoder.Decode(&oldObj); err != nil { + return nil, fmt.Errorf("cannot decode incoming old object: %v", err) + } + } + var patches duck.JSONPatch + + var err error + // Skip this step if the type we're dealing with is a duck type, since it is inherently + // incomplete and this will patch away all of the unspecified fields. + if _, ok := newObj.(duck.Populatable); !ok { + // Add these before defaulting fields, otherwise defaulting may cause an illegal patch + // because it expects the round tripped through Golang fields to be present already. + rtp, err := roundTripPatch(newBytes, newObj) + if err != nil { + return nil, fmt.Errorf("cannot create patch for round tripped newBytes: %v", err) + } + patches = append(patches, rtp...) + } + + // Set up the context for defaulting and validation + if oldObj != nil { + // Copy the old object and set defaults so that we don't reject our own + // defaulting done earlier in the webhook. + oldObj = oldObj.DeepCopyObject().(GenericCRD) + oldObj.SetDefaults(ctx) + + s, ok := oldObj.(apis.HasSpec) + if ok { + SetUserInfoAnnotations(s, ctx, req.Resource.Group) + } + + if req.SubResource == "" { + ctx = apis.WithinUpdate(ctx, oldObj) + } else { + ctx = apis.WithinSubResourceUpdate(ctx, oldObj, req.SubResource) + } + } else { + ctx = apis.WithinCreate(ctx) + } + ctx = apis.WithUserInfo(ctx, &req.UserInfo) + + // Default the new object. + if patches, err = setDefaults(ctx, patches, newObj); err != nil { + logger.Errorw("Failed the resource specific defaulter", zap.Error(err)) + // Return the error message as-is to give the defaulter callback + // discretion over (our portion of) the message that the user sees. + return nil, err + } + + if patches, err = ac.setUserInfoAnnotations(ctx, patches, newObj, req.Resource.Group); err != nil { + logger.Errorw("Failed the resource user info annotator", zap.Error(err)) + return nil, err + } + + // None of the validators will accept a nil value for newObj. + if newObj == nil { + return nil, errMissingNewObject + } + if err := validate(ctx, newObj); err != nil { + logger.Errorw("Failed the resource specific validation", zap.Error(err)) + // Return the error message as-is to give the validation callback + // discretion over (our portion of) the message that the user sees. + return nil, err + } + + return json.Marshal(patches) +} + +func (ac *ResourceAdmissionController) setUserInfoAnnotations(ctx context.Context, patches duck.JSONPatch, new GenericCRD, groupName string) (duck.JSONPatch, error) { + if new == nil { + return patches, nil + } + nh, ok := new.(apis.HasSpec) + if !ok { + return patches, nil + } + + b, a := new.DeepCopyObject().(apis.HasSpec), nh + + SetUserInfoAnnotations(nh, ctx, groupName) + + patch, err := duck.CreatePatch(b, a) + if err != nil { + return nil, err + } + return append(patches, patch...), nil +} + +// roundTripPatch generates the JSONPatch that corresponds to round tripping the given bytes through +// the Golang type (JSON -> Golang type -> JSON). Because it is not always true that +// bytes == json.Marshal(json.Unmarshal(bytes)). +// +// For example, if bytes did not contain a 'spec' field and the Golang type specifies its 'spec' +// field without omitempty, then by round tripping through the Golang type, we would have added +// `'spec': {}`. +func roundTripPatch(bytes []byte, unmarshalled interface{}) (duck.JSONPatch, error) { + if unmarshalled == nil { + return duck.JSONPatch{}, nil + } + marshaledBytes, err := json.Marshal(unmarshalled) + if err != nil { + return nil, fmt.Errorf("cannot marshal interface: %v", err) + } + return jsonpatch.CreatePatch(bytes, marshaledBytes) +} + +// validate performs validation on the provided "new" CRD. +// For legacy purposes, this also does apis.Immutable validation, +// which is deprecated and will be removed in a future release. +func validate(ctx context.Context, new apis.Validatable) error { + if apis.IsInUpdate(ctx) { + old := apis.GetBaseline(ctx) + if immutableNew, ok := new.(apis.Immutable); ok { + immutableOld, ok := old.(apis.Immutable) + if !ok { + return fmt.Errorf("unexpected type mismatch %T vs. %T", old, new) + } + if err := immutableNew.CheckImmutableFields(ctx, immutableOld); err != nil { + return err + } + } + } + + // Can't just `return new.Validate()` because it doesn't properly nil-check. + if err := new.Validate(ctx); err != nil { + return err + } + + return nil +} + +// setDefaults simply leverages apis.Defaultable to set defaults. +func setDefaults(ctx context.Context, patches duck.JSONPatch, crd GenericCRD) (duck.JSONPatch, error) { + before, after := crd.DeepCopyObject(), crd + after.SetDefaults(ctx) + + patch, err := duck.CreatePatch(before, after) + if err != nil { + return nil, err + } + + return append(patches, patch...), nil +} diff --git a/vendor/knative.dev/pkg/webhook/stats_reporter.go b/vendor/knative.dev/pkg/webhook/stats_reporter.go new file mode 100644 index 0000000000..d6c4df35c0 --- /dev/null +++ b/vendor/knative.dev/pkg/webhook/stats_reporter.go @@ -0,0 +1,143 @@ +/* +Copyright 2019 The Knative 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 ( + "context" + "strconv" + "time" + + "go.opencensus.io/stats" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" + admissionv1beta1 "k8s.io/api/admission/v1beta1" + "knative.dev/pkg/metrics" +) + +const ( + requestCountName = "request_count" + requestLatenciesName = "request_latencies" +) + +var ( + requestCountM = stats.Int64( + requestCountName, + "The number of requests that are routed to webhook", + stats.UnitDimensionless) + responseTimeInMsecM = stats.Float64( + requestLatenciesName, + "The response time in milliseconds", + stats.UnitMilliseconds) + + // Create the tag keys that will be used to add tags to our measurements. + // Tag keys must conform to the restrictions described in + // go.opencensus.io/tag/validate.go. Currently those restrictions are: + // - length between 1 and 255 inclusive + // - characters are printable US-ASCII + requestOperationKey = tag.MustNewKey("request_operation") + kindGroupKey = tag.MustNewKey("kind_group") + kindVersionKey = tag.MustNewKey("kind_version") + kindKindKey = tag.MustNewKey("kind_kind") + resourceGroupKey = tag.MustNewKey("resource_group") + resourceVersionKey = tag.MustNewKey("resource_version") + resourceResourceKey = tag.MustNewKey("resource_resource") + resourceNameKey = tag.MustNewKey("resource_name") + resourceNamespaceKey = tag.MustNewKey("resource_namespace") + admissionAllowedKey = tag.MustNewKey("admission_allowed") +) + +func init() { + register() +} + +// StatsReporter reports webhook metrics +type StatsReporter interface { + ReportRequest(request *admissionv1beta1.AdmissionRequest, response *admissionv1beta1.AdmissionResponse, d time.Duration) error +} + +// reporter implements StatsReporter interface +type reporter struct { + ctx context.Context +} + +// NewStatsReporter creaters a reporter for webhook metrics +func NewStatsReporter() (StatsReporter, error) { + ctx, err := tag.New( + context.Background(), + ) + if err != nil { + return nil, err + } + + return &reporter{ctx: ctx}, nil +} + +// Captures req count metric, recording the count and the duration +func (r *reporter) ReportRequest(req *admissionv1beta1.AdmissionRequest, resp *admissionv1beta1.AdmissionResponse, d time.Duration) error { + ctx, err := tag.New( + r.ctx, + tag.Insert(requestOperationKey, string(req.Operation)), + tag.Insert(kindGroupKey, req.Kind.Group), + tag.Insert(kindVersionKey, req.Kind.Version), + tag.Insert(kindKindKey, req.Kind.Kind), + tag.Insert(resourceGroupKey, req.Resource.Group), + tag.Insert(resourceVersionKey, req.Resource.Version), + tag.Insert(resourceResourceKey, req.Resource.Resource), + tag.Insert(resourceNameKey, req.Name), + tag.Insert(resourceNamespaceKey, req.Namespace), + tag.Insert(admissionAllowedKey, strconv.FormatBool(resp.Allowed)), + ) + if err != nil { + return err + } + + metrics.Record(ctx, requestCountM.M(1)) + // Convert time.Duration in nanoseconds to milliseconds + metrics.Record(ctx, responseTimeInMsecM.M(float64(d/time.Millisecond))) + return nil +} + +func register() { + tagKeys := []tag.Key{ + requestOperationKey, + kindGroupKey, + kindVersionKey, + kindKindKey, + resourceGroupKey, + resourceVersionKey, + resourceResourceKey, + resourceNamespaceKey, + resourceNameKey, + admissionAllowedKey} + + if err := view.Register( + &view.View{ + Description: requestCountM.Description(), + Measure: requestCountM, + Aggregation: view.Count(), + TagKeys: tagKeys, + }, + &view.View{ + Description: responseTimeInMsecM.Description(), + Measure: responseTimeInMsecM, + Aggregation: view.Distribution(metrics.Buckets125(1, 100000)...), // [1 2 5 10 20 50 100 200 500 1000 2000 5000 10000 20000 50000 100000]ms + TagKeys: tagKeys, + }, + ); err != nil { + panic(err) + } +} diff --git a/vendor/knative.dev/pkg/webhook/user_info.go b/vendor/knative.dev/pkg/webhook/user_info.go new file mode 100644 index 0000000000..405290e7a7 --- /dev/null +++ b/vendor/knative.dev/pkg/webhook/user_info.go @@ -0,0 +1,52 @@ +/* +Copyright 2019 The Knative 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 ( + "context" + + "k8s.io/apimachinery/pkg/api/equality" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/apis" +) + +// SetUserInfoAnnotations sets creator and updater annotations on a resource. +func SetUserInfoAnnotations(resource apis.HasSpec, ctx context.Context, groupName string) { + if ui := apis.GetUserInfo(ctx); ui != nil { + objectMetaAccessor, ok := resource.(metav1.ObjectMetaAccessor) + if !ok { + return + } + + annotations := objectMetaAccessor.GetObjectMeta().GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + objectMetaAccessor.GetObjectMeta().SetAnnotations(annotations) + } + + if apis.IsInUpdate(ctx) { + old := apis.GetBaseline(ctx).(apis.HasSpec) + if equality.Semantic.DeepEqual(old.GetUntypedSpec(), resource.GetUntypedSpec()) { + return + } + annotations[groupName+apis.UpdaterAnnotationSuffix] = ui.Username + } else { + annotations[groupName+apis.CreatorAnnotationSuffix] = ui.Username + annotations[groupName+apis.UpdaterAnnotationSuffix] = ui.Username + } + } +} diff --git a/vendor/knative.dev/pkg/webhook/webhook.go b/vendor/knative.dev/pkg/webhook/webhook.go new file mode 100644 index 0000000000..1aca8fc400 --- /dev/null +++ b/vendor/knative.dev/pkg/webhook/webhook.go @@ -0,0 +1,386 @@ +/* +Copyright 2017 The Knative 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 ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/json" + "errors" + "fmt" + "net/http" + "time" + + "go.uber.org/zap" + "golang.org/x/sync/errgroup" + "knative.dev/pkg/logging" + "knative.dev/pkg/logging/logkey" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +const ( + secretServerKey = "server-key.pem" + secretServerCert = "server-cert.pem" + secretCACert = "ca-cert.pem" +) + +var ( + errMissingNewObject = errors.New("the new object may not be nil") +) + +// ControllerOptions contains the configuration for the webhook +type ControllerOptions struct { + // ResourceMutatingWebhookName is the name of the webhook we create to handle + // mutations before they get stored in the storage. + ResourceMutatingWebhookName string + + // ConfigValidationWebhookName is the name of the webhook we create to handle + // mutations before they get stored in the storage. + ConfigValidationWebhookName string + + // ServiceName is the service name of the webhook. + ServiceName string + + // SecretName is the name of k8s secret that contains the webhook + // server key/cert and corresponding CA cert that signed them. The + // server key/cert are used to serve the webhook and the CA cert + // is provided to k8s apiserver during admission controller + // registration. + SecretName string + + // Namespace is the namespace in which everything above lives. + Namespace string + + // Port where the webhook is served. Per k8s admission + // registration requirements this should be 443 unless there is + // only a single port for the service. + Port int + + // RegistrationDelay controls how long admission registration + // occurs after the webhook is started. This is used to avoid + // potential races where registration completes and k8s apiserver + // invokes the webhook before the HTTP server is started. + RegistrationDelay time.Duration + + // ClientAuthType declares the policy the webhook server will follow for + // TLS Client Authentication. + // The default value is tls.NoClientCert. + ClientAuth tls.ClientAuthType + + // StatsReporter reports metrics about the webhook. + // This will be automatically initialized by the constructor if left uninitialized. + StatsReporter StatsReporter + + // Service path for ResourceAdmissionController webhook + // Default is "/" for backward compatibility and is set by the constructor + ResourceAdmissionControllerPath string + + // Service path for ConfigValidationController webhook + // Default is "/config-validation" and is set by the constructor + ConfigValidationControllerPath string +} + +// AdmissionController provides the interface for different admission controllers +type AdmissionController interface { + Admit(context.Context, *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse + Register(context.Context, kubernetes.Interface, []byte) error +} + +// Webhook implements the external webhook for validation of +// resources and configuration. +type Webhook struct { + Client kubernetes.Interface + Options ControllerOptions + Logger *zap.SugaredLogger + admissionControllers map[string]AdmissionController + + WithContext func(context.Context) context.Context +} + +// New constructs a Webhook +func New( + client kubernetes.Interface, + opts ControllerOptions, + admissionControllers map[string]AdmissionController, + logger *zap.SugaredLogger, + ctx func(context.Context) context.Context, +) (*Webhook, error) { + + if opts.StatsReporter == nil { + reporter, err := NewStatsReporter() + if err != nil { + return nil, err + } + opts.StatsReporter = reporter + } + + return &Webhook{ + Client: client, + Options: opts, + admissionControllers: admissionControllers, + Logger: logger, + WithContext: ctx, + }, nil +} + +// Run implements the admission controller run loop. +func (ac *Webhook) Run(stop <-chan struct{}) error { + logger := ac.Logger + ctx := logging.WithLogger(context.TODO(), logger) + tlsConfig, caCert, err := configureCerts(ctx, ac.Client, &ac.Options) + if err != nil { + logger.Errorw("could not configure admission webhook certs", zap.Error(err)) + return err + } + + server := &http.Server{ + Handler: ac, + Addr: fmt.Sprintf(":%v", ac.Options.Port), + TLSConfig: tlsConfig, + } + + logger.Info("Found certificates for webhook...") + if ac.Options.RegistrationDelay != 0 { + logger.Infof("Delaying admission webhook registration for %v", ac.Options.RegistrationDelay) + } + + eg, ctx := errgroup.WithContext(ctx) + eg.Go(func() error { + select { + case <-time.After(ac.Options.RegistrationDelay): + // Wait an initial delay before registering + case <-stop: + return nil + } + // Register the webhook, and then periodically check that it is up to date. + for { + for _, c := range ac.admissionControllers { + if err := c.Register(ctx, ac.Client, caCert); err != nil { + logger.Errorw("failed to register webhook", zap.Error(err)) + return err + } + } + logger.Info("Successfully registered webhook") + select { + case <-time.After(10 * time.Minute): + case <-stop: + return nil + } + } + }) + eg.Go(func() error { + if err := server.ListenAndServeTLS("", ""); err != nil { + logger.Errorw("ListenAndServeTLS for admission webhook returned error", zap.Error(err)) + return err + } + return nil + }) + + select { + case <-stop: + return server.Close() + case <-ctx.Done(): + return fmt.Errorf("webhook server bootstrap failed %v", err) + } +} + +// ServeHTTP implements the external admission webhook for mutating +// serving resources. +func (ac *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { + var ttStart = time.Now() + logger := ac.Logger + logger.Infof("Webhook ServeHTTP request=%#v", r) + + // Verify the content type is accurate. + contentType := r.Header.Get("Content-Type") + if contentType != "application/json" { + http.Error(w, "invalid Content-Type, want `application/json`", http.StatusUnsupportedMediaType) + return + } + + var review admissionv1beta1.AdmissionReview + if err := json.NewDecoder(r.Body).Decode(&review); err != nil { + http.Error(w, fmt.Sprintf("could not decode body: %v", err), http.StatusBadRequest) + return + } + + logger = logger.With( + zap.String(logkey.Kind, fmt.Sprint(review.Request.Kind)), + zap.String(logkey.Namespace, review.Request.Namespace), + zap.String(logkey.Name, review.Request.Name), + zap.String(logkey.Operation, fmt.Sprint(review.Request.Operation)), + zap.String(logkey.Resource, fmt.Sprint(review.Request.Resource)), + zap.String(logkey.SubResource, fmt.Sprint(review.Request.SubResource)), + zap.String(logkey.UserInfo, fmt.Sprint(review.Request.UserInfo))) + ctx := logging.WithLogger(r.Context(), logger) + + if ac.WithContext != nil { + ctx = ac.WithContext(ctx) + } + + if _, ok := ac.admissionControllers[r.URL.Path]; !ok { + http.Error(w, fmt.Sprintf("no admission controller registered for: %s", r.URL.Path), http.StatusBadRequest) + return + } + + c := ac.admissionControllers[r.URL.Path] + reviewResponse := c.Admit(ctx, review.Request) + var response admissionv1beta1.AdmissionReview + if reviewResponse != nil { + response.Response = reviewResponse + response.Response.UID = review.Request.UID + } + + logger.Infof("AdmissionReview for %#v: %s/%s response=%#v", + review.Request.Kind, review.Request.Namespace, review.Request.Name, reviewResponse) + + if err := json.NewEncoder(w).Encode(response); err != nil { + http.Error(w, fmt.Sprintf("could encode response: %v", err), http.StatusInternalServerError) + return + } + + if ac.Options.StatsReporter != nil { + // Only report valid requests + ac.Options.StatsReporter.ReportRequest(review.Request, response.Response, time.Since(ttStart)) + } +} + +// GetAPIServerExtensionCACert gets the Kubernetes aggregate apiserver +// client CA cert used by validator. +// +// NOTE: this certificate is provided kubernetes. We do not control +// its name or location. +func getAPIServerExtensionCACert(cl kubernetes.Interface) ([]byte, error) { + const name = "extension-apiserver-authentication" + c, err := cl.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + const caFileName = "requestheader-client-ca-file" + pem, ok := c.Data[caFileName] + if !ok { + return nil, fmt.Errorf("cannot find %s in ConfigMap %s: ConfigMap.Data is %#v", caFileName, name, c.Data) + } + return []byte(pem), nil +} + +// MakeTLSConfig makes a TLS configuration suitable for use with the server +func makeTLSConfig(serverCert, serverKey, caCert []byte, clientAuthType tls.ClientAuthType) (*tls.Config, error) { + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + cert, err := tls.X509KeyPair(serverCert, serverKey) + if err != nil { + return nil, err + } + return &tls.Config{ + Certificates: []tls.Certificate{cert}, + ClientCAs: caCertPool, + ClientAuth: clientAuthType, + }, nil +} + +func getOrGenerateKeyCertsFromSecret(ctx context.Context, client kubernetes.Interface, + options *ControllerOptions) (serverKey, serverCert, caCert []byte, err error) { + logger := logging.FromContext(ctx) + secret, err := client.CoreV1().Secrets(options.Namespace).Get(options.SecretName, metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return nil, nil, nil, err + } + logger.Info("Did not find existing secret, creating one") + newSecret, err := generateSecret(ctx, options) + if err != nil { + return nil, nil, nil, err + } + secret, err = client.CoreV1().Secrets(newSecret.Namespace).Create(newSecret) + if err != nil { + if !apierrors.IsAlreadyExists(err) { + return nil, nil, nil, err + } + // OK, so something else might have created, try fetching it instead. + secret, err = client.CoreV1().Secrets(options.Namespace).Get(options.SecretName, metav1.GetOptions{}) + if err != nil { + return nil, nil, nil, err + } + } + } + + var ok bool + if serverKey, ok = secret.Data[secretServerKey]; !ok { + return nil, nil, nil, errors.New("server key missing") + } + if serverCert, ok = secret.Data[secretServerCert]; !ok { + return nil, nil, nil, errors.New("server cert missing") + } + if caCert, ok = secret.Data[secretCACert]; !ok { + return nil, nil, nil, errors.New("ca cert missing") + } + return serverKey, serverCert, caCert, nil +} + +func configureCerts(ctx context.Context, client kubernetes.Interface, options *ControllerOptions) (*tls.Config, []byte, error) { + var apiServerCACert []byte + if options.ClientAuth >= tls.VerifyClientCertIfGiven { + var err error + apiServerCACert, err = getAPIServerExtensionCACert(client) + if err != nil { + return nil, nil, err + } + } + + serverKey, serverCert, caCert, err := getOrGenerateKeyCertsFromSecret(ctx, client, options) + if err != nil { + return nil, nil, err + } + tlsConfig, err := makeTLSConfig(serverCert, serverKey, apiServerCACert, options.ClientAuth) + if err != nil { + return nil, nil, err + } + return tlsConfig, caCert, nil +} + +func makeErrorStatus(reason string, args ...interface{}) *admissionv1beta1.AdmissionResponse { + result := apierrors.NewBadRequest(fmt.Sprintf(reason, args...)).Status() + return &admissionv1beta1.AdmissionResponse{ + Result: &result, + Allowed: false, + } +} + +func generateSecret(ctx context.Context, options *ControllerOptions) (*corev1.Secret, error) { + serverKey, serverCert, caCert, err := CreateCerts(ctx, options.ServiceName, options.Namespace) + if err != nil { + return nil, err + } + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: options.SecretName, + Namespace: options.Namespace, + }, + Data: map[string][]byte{ + secretServerKey: serverKey, + secretServerCert: serverCert, + secretCACert: caCert, + }, + }, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 9dc90c147d..c0eaf78f6b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -72,6 +72,8 @@ github.com/go-openapi/jsonreference github.com/go-openapi/spec # github.com/go-openapi/swag v0.19.2 github.com/go-openapi/swag +# github.com/gobuffalo/envy v1.6.5 +github.com/gobuffalo/envy # github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d github.com/gogo/protobuf/proto github.com/gogo/protobuf/sortkeys @@ -81,9 +83,9 @@ github.com/golang/groupcache/lru github.com/golang/protobuf/proto github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes -github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/timestamp github.com/golang/protobuf/ptypes/wrappers +github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/struct github.com/golang/protobuf/ptypes/empty github.com/golang/protobuf/protoc-gen-go/descriptor @@ -131,6 +133,8 @@ github.com/imdario/mergo github.com/inconshreveable/mousetrap # github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af github.com/jmespath/go-jmespath +# github.com/joho/godotenv v1.3.0 +github.com/joho/godotenv # github.com/json-iterator/go v1.1.7 github.com/json-iterator/go # github.com/magiconair/properties v1.8.0 @@ -139,6 +143,8 @@ github.com/magiconair/properties github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter github.com/mailru/easyjson/buffer +# github.com/markbates/inflect v1.0.4 +github.com/markbates/inflect # github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a github.com/mattbaird/jsonpatch # github.com/matttproud/golang_protobuf_extensions v1.0.1 @@ -170,6 +176,8 @@ github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg # github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs +# github.com/robfig/cron v1.2.0 +github.com/robfig/cron # github.com/russross/blackfriday/v2 v2.0.1 github.com/russross/blackfriday/v2 # github.com/shurcooL/sanitized_anchor_name v1.0.0 @@ -238,6 +246,7 @@ golang.org/x/oauth2/internal golang.org/x/oauth2/jws golang.org/x/oauth2/jwt # golang.org/x/sync v0.0.0-20190423024810-112230192c58 +golang.org/x/sync/errgroup golang.org/x/sync/semaphore # golang.org/x/sys v0.0.0-20191010194322-b09406accb47 golang.org/x/sys/unix @@ -259,9 +268,9 @@ golang.org/x/time/rate # google.golang.org/api v0.7.0 google.golang.org/api/option google.golang.org/api/support/bundler +google.golang.org/api/internal google.golang.org/api/iterator google.golang.org/api/transport -google.golang.org/api/internal google.golang.org/api/transport/grpc google.golang.org/api/transport/http google.golang.org/api/googleapi/transport @@ -295,7 +304,7 @@ google.golang.org/genproto/protobuf/field_mask google.golang.org/grpc google.golang.org/grpc/codes google.golang.org/grpc/metadata -google.golang.org/grpc/status +google.golang.org/grpc/naming google.golang.org/grpc/balancer google.golang.org/grpc/balancer/roundrobin google.golang.org/grpc/connectivity @@ -313,21 +322,21 @@ google.golang.org/grpc/internal/grpcrand google.golang.org/grpc/internal/grpcsync google.golang.org/grpc/internal/transport google.golang.org/grpc/keepalive -google.golang.org/grpc/naming google.golang.org/grpc/peer google.golang.org/grpc/resolver google.golang.org/grpc/resolver/dns google.golang.org/grpc/resolver/passthrough google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats +google.golang.org/grpc/status google.golang.org/grpc/tap -google.golang.org/grpc/balancer/grpclb -google.golang.org/grpc/credentials/google -google.golang.org/grpc/credentials/oauth google.golang.org/grpc/balancer/base google.golang.org/grpc/credentials/internal google.golang.org/grpc/binarylog/grpc_binarylog_v1 google.golang.org/grpc/internal/syscall +google.golang.org/grpc/balancer/grpclb +google.golang.org/grpc/credentials/google +google.golang.org/grpc/credentials/oauth google.golang.org/grpc/balancer/grpclb/grpc_lb_v1 google.golang.org/grpc/credentials/alts google.golang.org/grpc/credentials/alts/internal @@ -383,6 +392,7 @@ k8s.io/api/settings/v1alpha1 k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 +k8s.io/api/admission/v1beta1 # k8s.io/apimachinery v0.0.0-20190817020851-f2f3a405f61d k8s.io/apimachinery/pkg/api/errors k8s.io/apimachinery/pkg/apis/meta/v1 @@ -414,10 +424,10 @@ k8s.io/apimachinery/pkg/util/net k8s.io/apimachinery/pkg/util/yaml k8s.io/apimachinery/pkg/runtime/serializer k8s.io/apimachinery/third_party/forked/golang/reflect +k8s.io/apimachinery/pkg/runtime/serializer/streaming k8s.io/apimachinery/pkg/apis/meta/v1/unstructured k8s.io/apimachinery/pkg/util/mergepatch k8s.io/apimachinery/third_party/forked/golang/json -k8s.io/apimachinery/pkg/runtime/serializer/streaming k8s.io/apimachinery/pkg/runtime/serializer/json k8s.io/apimachinery/pkg/runtime/serializer/versioning k8s.io/apimachinery/pkg/apis/meta/v1/validation @@ -610,7 +620,18 @@ k8s.io/kube-openapi/pkg/common k8s.io/utils/integer k8s.io/utils/buffer k8s.io/utils/trace -# knative.dev/pkg v0.0.0-20191022181926-0b19b4ad9139 +# knative.dev/eventing v0.10.0 +knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1 +knative.dev/eventing/pkg/apis/sources/v1alpha1 +knative.dev/eventing/pkg/client/clientset/versioned/scheme +knative.dev/eventing/pkg/apis/duck +knative.dev/eventing/pkg/apis/sources +knative.dev/eventing/pkg/apis/eventing/v1alpha1 +knative.dev/eventing/pkg/apis/messaging/v1alpha1 +knative.dev/eventing/pkg/apis/duck/v1alpha1 +knative.dev/eventing/pkg/apis/eventing +knative.dev/eventing/pkg/apis/messaging +# knative.dev/pkg v0.0.0-20191025185335-cad41c40ccb5 knative.dev/pkg/apis knative.dev/pkg/apis/duck/v1 knative.dev/pkg/ptr @@ -624,6 +645,7 @@ knative.dev/pkg/configmap knative.dev/pkg/logging knative.dev/pkg/network knative.dev/pkg/apis/duck/v1beta1 +knative.dev/pkg/webhook knative.dev/pkg/changeset knative.dev/pkg/logging/logkey knative.dev/pkg/controller