diff --git a/controllers/nmstate_controller.go b/controllers/nmstate_controller.go index 96a26c2e7..7464a21e3 100644 --- a/controllers/nmstate_controller.go +++ b/controllers/nmstate_controller.go @@ -173,6 +173,7 @@ func (r *NMStateReconciler) applyHandler(instance *nmstatev1beta1.NMState) error data.Data["CARotateInterval"] = "" data.Data["CAOverlapInterval"] = "" data.Data["CertRotateInterval"] = "" + data.Data["CertOverlapInterval"] = "" return r.renderAndApply(instance, data, "handler", true) } diff --git a/deploy/handler/operator.yaml b/deploy/handler/operator.yaml index 927313afa..c8942fc6b 100644 --- a/deploy/handler/operator.yaml +++ b/deploy/handler/operator.yaml @@ -59,9 +59,11 @@ spec: - name: CA_ROTATE_INTERVAL value: {{ .CARotateInterval | default "8760h0m0s" }} - name: CA_OVERLAP_INTERVAL - value: {{ .CAOverlapInterval | default "8760h0m0s" }} + value: {{ .CAOverlapInterval | default "24h0m0s" }} - name: CERT_ROTATE_INTERVAL value: {{ .CertRotateInterval | default "4380h0m0s" }} + - name: CERT_OVERLAP_INTERVAL + value: {{ .CertOverlapInterval | default "24h0m0s" }} ports: - containerPort: 8443 name: webhook-server diff --git a/go.mod b/go.mod index c964c7ba4..9eda3bc17 100644 --- a/go.mod +++ b/go.mod @@ -11,14 +11,14 @@ require ( github.com/gobwas/glob v0.2.3 github.com/kelseyhightower/envconfig v1.4.0 github.com/nightlyone/lockfile v1.0.0 - github.com/onsi/ginkgo v1.14.0 - github.com/onsi/gomega v1.10.1 + github.com/onsi/ginkgo v1.15.0 + github.com/onsi/gomega v1.10.5 github.com/openshift/cluster-network-operator v0.0.0-20200922032245-f47200e8dbc0 github.com/operator-framework/operator-registry v1.14.3 github.com/operator-framework/operator-sdk v1.2.0 github.com/phoracek/networkmanager-go v0.1.0 github.com/pkg/errors v0.9.1 - github.com/qinqon/kube-admission-webhook v0.12.0 + github.com/qinqon/kube-admission-webhook v0.13.0 github.com/tidwall/gjson v1.6.1 k8s.io/api v0.18.9 k8s.io/apimachinery v0.18.9 diff --git a/go.sum b/go.sum index 848c71147..25b13b863 100644 --- a/go.sum +++ b/go.sum @@ -1034,6 +1034,8 @@ github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= +github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= @@ -1048,6 +1050,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= +github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1216,8 +1220,8 @@ github.com/prometheus/prometheus v2.3.2+incompatible/go.mod h1:oAIUtOny2rjMX0OWN github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/psampaz/go-mod-outdated v0.5.0/go.mod h1:Ow0f464qFSBVyz//3QyVLNPtL8/lLvjouMnjmVzNT/U= github.com/psampaz/go-mod-outdated v0.6.0/go.mod h1:r78NYWd1z+F9Zdsfy70svgXOz363B08BWnTyFSgEESs= -github.com/qinqon/kube-admission-webhook v0.12.0 h1:5VLcdJo7JWjIhjqjrLZT/ry80J7/sZ83EUmTPFeXIGQ= -github.com/qinqon/kube-admission-webhook v0.12.0/go.mod h1:VX4R05NoFy8Tm/571Dg0GIjTvhFEsTe7QLYdKuuTfrE= +github.com/qinqon/kube-admission-webhook v0.13.0 h1:NRm8+BvfNWuW3ydwtsIXTkw3qdC6q5qVlDkrRgjRbaU= +github.com/qinqon/kube-admission-webhook v0.13.0/go.mod h1:dVYCzQ9WsJc3jUxsO0U49nj2/Pl5UFHiq04oXQhJzfM= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= @@ -1404,6 +1408,7 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= @@ -1517,6 +1522,8 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1565,6 +1572,9 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYc golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1581,6 +1591,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEha golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1648,6 +1660,9 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1719,12 +1734,16 @@ golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e h1:3Dzrrxi54Io7Aoyb0PYLsI4 golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5 h1:UaoXseXAWUJUcuJ2E2oczJdLxAJXL0lOmVaBl7kuk+I= golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= gomodules.xyz/jsonpatch/v3 v3.0.1 h1:Te7hKxV52TKCbNYq3t84tzKav3xhThdvSsSp/W89IyI= diff --git a/main.go b/main.go index 03f26cb98..a6df925e7 100644 --- a/main.go +++ b/main.go @@ -127,6 +127,11 @@ func main() { setupLog.Error(err, "Failed retrieving cert rotate interval") os.Exit(1) } + webhookOpts.CertOverlapInterval, err = environment.LookupAsDuration("CERT_OVERLAP_INTERVAL") + if err != nil { + setupLog.Error(err, "Failed retrieving cert overlap interval") + os.Exit(1) + } if err := webhook.AddToManager(mgr, webhookOpts); err != nil { setupLog.Error(err, "Cannot initialize webhook") diff --git a/vendor/github.com/onsi/ginkgo/.travis.yml b/vendor/github.com/onsi/ginkgo/.travis.yml index 079af2431..8b2883f97 100644 --- a/vendor/github.com/onsi/ginkgo/.travis.yml +++ b/vendor/github.com/onsi/ginkgo/.travis.yml @@ -1,7 +1,7 @@ language: go go: - - 1.13.x - 1.14.x + - 1.15.x - tip cache: @@ -16,10 +16,9 @@ install: - GO111MODULE="off" go get golang.org/x/tools/cmd/cover - GO111MODULE="off" go get github.com/onsi/gomega - GO111MODULE="off" go install github.com/onsi/ginkgo/ginkgo - - export PATH=$PATH:$HOME/gopath/bin + - export PATH=$GOPATH/bin:$PATH script: - - GO111MODULE="on" go mod tidy - - diff -u <(echo -n) <(git diff go.mod) - - diff -u <(echo -n) <(git diff go.sum) - - $HOME/gopath/bin/ginkgo -r --randomizeAllSpecs --randomizeSuites --race --trace && go vet + - GO111MODULE="on" go mod tidy && git diff --exit-code go.mod go.sum + - go vet + - ginkgo -r --randomizeAllSpecs --randomizeSuites --race --trace diff --git a/vendor/github.com/onsi/ginkgo/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/CHANGELOG.md index bdf18327e..bf51fe9cd 100644 --- a/vendor/github.com/onsi/ginkgo/CHANGELOG.md +++ b/vendor/github.com/onsi/ginkgo/CHANGELOG.md @@ -1,3 +1,25 @@ +## 1.15.0 + +### Features +- Adds 'outline' command to print the outline of specs/containers in a file (#754) [071c369] [6803cc3] [935b538] [06744e8] [0c40583] +- Add support for using template to generate tests (#752) [efb9e69] +- Add a Chinese Doc #755 (#756) [5207632] +- cli: allow multiple -focus and -skip flags (#736) [9a782fb] + +### Fixes +- Add _internal to filename of tests created with internal flag (#751) [43c12da] + +## 1.14.2 + +### Fixes +- correct handling windows backslash in import path (#721) [97f3d51] +- Add additional methods to GinkgoT() to improve compatibility with the testing.TB interface [b5fe44d] + +## 1.14.1 + +### Fixes +- Discard exported method declaration when running ginkgo bootstrap (#558) [f4b0240] + ## 1.14.0 ### Features diff --git a/vendor/github.com/onsi/ginkgo/README.md b/vendor/github.com/onsi/ginkgo/README.md index fab114580..64e85eee0 100644 --- a/vendor/github.com/onsi/ginkgo/README.md +++ b/vendor/github.com/onsi/ginkgo/README.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.org/onsi/ginkgo.svg?branch=master)](https://travis-ci.org/onsi/ginkgo) -Jump to the [docs](https://onsi.github.io/ginkgo/) to learn more. To start rolling your Ginkgo tests *now* [keep reading](#set-me-up)! +Jump to the [docs](https://onsi.github.io/ginkgo/) | [中文文档](https://ke-chain.github.io/ginkgodoc) to learn more. To start rolling your Ginkgo tests *now* [keep reading](#set-me-up)! If you have a question, comment, bug report, feature request, etc. please open a GitHub issue, or visit the [Ginkgo Slack channel](https://app.slack.com/client/T029RQSE6/CQQ50BBNW). @@ -80,10 +80,11 @@ Agouti allows you run WebDriver integration tests. Learn more about Agouti [her You'll need the Go command-line tools. Follow the [installation instructions](https://golang.org/doc/install) if you don't have it installed. ### Global installation -To install the Ginkgo command line interface into the `$PATH` (actually to `$GOBIN`): +To install the Ginkgo command line interface: ```bash go get -u github.com/onsi/ginkgo/ginkgo ``` +Note that this will install it to `$GOBIN`, which will need to be in the `$PATH` (or equivalent). Run `go help install` for more information. ### Go module ["tools package"](https://github.com/golang/go/issues/25922): Create (or update) a file called `tools/tools.go` with the following contents: @@ -93,7 +94,7 @@ Create (or update) a file called `tools/tools.go` with the following contents: package tools import ( - _ "github.com/onsi/ginkgo" + _ "github.com/onsi/ginkgo/ginkgo" ) // This file imports packages that are used when running go generate, or used diff --git a/vendor/github.com/onsi/ginkgo/config/config.go b/vendor/github.com/onsi/ginkgo/config/config.go index 2ae48b804..8c177811e 100644 --- a/vendor/github.com/onsi/ginkgo/config/config.go +++ b/vendor/github.com/onsi/ginkgo/config/config.go @@ -20,14 +20,14 @@ import ( "fmt" ) -const VERSION = "1.14.0" +const VERSION = "1.15.0" type GinkgoConfigType struct { RandomSeed int64 RandomizeAllSpecs bool RegexScansFilePath bool - FocusString string - SkipString string + FocusStrings []string + SkipStrings []string SkipMeasurements bool FailOnPending bool FailFast bool @@ -65,6 +65,11 @@ func processPrefix(prefix string) string { return prefix } +type flagFunc func(string) + +func (f flagFunc) String() string { return "" } +func (f flagFunc) Set(s string) error { f(s); return nil } + func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) { prefix = processPrefix(prefix) flagSet.Int64Var(&(GinkgoConfig.RandomSeed), prefix+"seed", time.Now().Unix(), "The seed used to randomize the spec suite.") @@ -75,8 +80,8 @@ func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) { flagSet.BoolVar(&(GinkgoConfig.DryRun), prefix+"dryRun", false, "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v.") - flagSet.StringVar(&(GinkgoConfig.FocusString), prefix+"focus", "", "If set, ginkgo will only run specs that match this regular expression.") - flagSet.StringVar(&(GinkgoConfig.SkipString), prefix+"skip", "", "If set, ginkgo will only run specs that do not match this regular expression.") + flagSet.Var(flagFunc(flagFocus), prefix+"focus", "If set, ginkgo will only run specs that match this regular expression. Can be specified multiple times, values are ORed.") + flagSet.Var(flagFunc(flagSkip), prefix+"skip", "If set, ginkgo will only run specs that do not match this regular expression. Can be specified multiple times, values are ORed.") flagSet.BoolVar(&(GinkgoConfig.RegexScansFilePath), prefix+"regexScansFilePath", false, "If set, ginkgo regex matching also will look at the file path (code location).") @@ -133,12 +138,12 @@ func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultRepor result = append(result, fmt.Sprintf("--%sdryRun", prefix)) } - if ginkgo.FocusString != "" { - result = append(result, fmt.Sprintf("--%sfocus=%s", prefix, ginkgo.FocusString)) + for _, s := range ginkgo.FocusStrings { + result = append(result, fmt.Sprintf("--%sfocus=%s", prefix, s)) } - if ginkgo.SkipString != "" { - result = append(result, fmt.Sprintf("--%sskip=%s", prefix, ginkgo.SkipString)) + for _, s := range ginkgo.SkipStrings { + result = append(result, fmt.Sprintf("--%sskip=%s", prefix, s)) } if ginkgo.FlakeAttempts > 1 { @@ -211,3 +216,13 @@ func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultRepor return result } + +// flagFocus implements the -focus flag. +func flagFocus(arg string) { + GinkgoConfig.FocusStrings = append(GinkgoConfig.FocusStrings, arg) +} + +// flagSkip implements the -skip flag. +func flagSkip(arg string) { + GinkgoConfig.SkipStrings = append(GinkgoConfig.SkipStrings, arg) +} diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go b/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go index 4099f99a8..288df7797 100644 --- a/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go +++ b/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go @@ -4,6 +4,7 @@ import ( "bytes" "flag" "fmt" + "io/ioutil" "os" "path/filepath" "strconv" @@ -12,11 +13,15 @@ import ( ) func BuildGenerateCommand() *Command { - var agouti, noDot, internal bool + var ( + agouti, noDot, internal bool + customTestFile string + ) flagSet := flag.NewFlagSet("generate", flag.ExitOnError) flagSet.BoolVar(&agouti, "agouti", false, "If set, generate will generate a test file for writing Agouti tests") flagSet.BoolVar(&noDot, "nodot", false, "If set, generate will generate a test file that does not . import ginkgo and gomega") flagSet.BoolVar(&internal, "internal", false, "If set, generate will generate a test file that uses the regular package name") + flagSet.StringVar(&customTestFile, "template", "", "If specified, generate will use the contents of the file passed as the test file template") return &Command{ Name: "generate", @@ -28,7 +33,7 @@ func BuildGenerateCommand() *Command { "Accepts the following flags:", }, Command: func(args []string, additionalArgs []string) { - generateSpec(args, agouti, noDot, internal) + generateSpec(args, agouti, noDot, internal, customTestFile) }, } } @@ -81,9 +86,9 @@ type specData struct { ImportPackage bool } -func generateSpec(args []string, agouti, noDot, internal bool) { +func generateSpec(args []string, agouti, noDot, internal bool, customTestFile string) { if len(args) == 0 { - err := generateSpecForSubject("", agouti, noDot, internal) + err := generateSpecForSubject("", agouti, noDot, internal, customTestFile) if err != nil { fmt.Println(err.Error()) fmt.Println("") @@ -95,7 +100,7 @@ func generateSpec(args []string, agouti, noDot, internal bool) { var failed bool for _, arg := range args { - err := generateSpecForSubject(arg, agouti, noDot, internal) + err := generateSpecForSubject(arg, agouti, noDot, internal, customTestFile) if err != nil { failed = true fmt.Println(err.Error()) @@ -107,13 +112,17 @@ func generateSpec(args []string, agouti, noDot, internal bool) { } } -func generateSpecForSubject(subject string, agouti, noDot, internal bool) error { +func generateSpecForSubject(subject string, agouti, noDot, internal bool, customTestFile string) error { packageName, specFilePrefix, formattedName := getPackageAndFormattedName() if subject != "" { specFilePrefix = formatSubject(subject) formattedName = prettifyPackageName(specFilePrefix) } + if internal { + specFilePrefix = specFilePrefix + "_internal" + } + data := specData{ Package: determinePackageName(packageName, internal), Subject: formattedName, @@ -136,7 +145,13 @@ func generateSpecForSubject(subject string, agouti, noDot, internal bool) error defer f.Close() var templateText string - if agouti { + if customTestFile != "" { + tpl, err := ioutil.ReadFile(customTestFile) + if err != nil { + panic(err.Error()) + } + templateText = string(tpl) + } else if agouti { templateText = agoutiSpecText } else { templateText = specText @@ -233,18 +248,20 @@ func getPackageImportPath() string { panic(err.Error()) } + sep := string(filepath.Separator) + // Try go.mod file first modRoot := findModuleRoot(workingDir) if modRoot != "" { modName := moduleName(modRoot) if modName != "" { cd := strings.Replace(workingDir, modRoot, "", -1) + cd = strings.ReplaceAll(cd, sep, "/") return modName + cd } } // Fallback to GOPATH structure - sep := string(filepath.Separator) paths := strings.Split(workingDir, sep+"src"+sep) if len(paths) == 1 { fmt.Printf("\nCouldn't identify package import path.\n\n\tginkgo generate\n\nMust be run within a package directory under $GOPATH/src/...\nYou're going to have to change UNKNOWN_PACKAGE_PATH in the generated file...\n\n") diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/main.go b/vendor/github.com/onsi/ginkgo/ginkgo/main.go index f60c48a72..ac725bf40 100644 --- a/vendor/github.com/onsi/ginkgo/ginkgo/main.go +++ b/vendor/github.com/onsi/ginkgo/ginkgo/main.go @@ -111,6 +111,11 @@ will output an executable file named `package.test`. This can be run directly o ginkgo + +To print an outline of Ginkgo specs and containers in a file: + + gingko outline + To print out Ginkgo's version: ginkgo version @@ -172,6 +177,7 @@ func init() { Commands = append(Commands, BuildUnfocusCommand()) Commands = append(Commands, BuildVersionCommand()) Commands = append(Commands, BuildHelpCommand()) + Commands = append(Commands, BuildOutlineCommand()) } func main() { diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go b/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go index 3f7237c60..c87b72165 100644 --- a/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go +++ b/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go @@ -186,7 +186,9 @@ func getExportedDeclarationsForFile(path string) ([]string, error) { declarations = append(declarations, s.Names[0].Name) } case *ast.FuncDecl: - declarations = append(declarations, x.Name.Name) + if x.Recv == nil { + declarations = append(declarations, x.Name.Name) + } } } diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/outline/ginkgo.go b/vendor/github.com/onsi/ginkgo/ginkgo/outline/ginkgo.go new file mode 100644 index 000000000..ce6b7fcd7 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/ginkgo/outline/ginkgo.go @@ -0,0 +1,243 @@ +package outline + +import ( + "go/ast" + "go/token" + "strconv" +) + +const ( + // undefinedTextAlt is used if the spec/container text cannot be derived + undefinedTextAlt = "undefined" +) + +// ginkgoMetadata holds useful bits of information for every entry in the outline +type ginkgoMetadata struct { + // Name is the spec or container function name, e.g. `Describe` or `It` + Name string `json:"name"` + + // Text is the `text` argument passed to specs, and some containers + Text string `json:"text"` + + // Start is the position of first character of the spec or container block + Start int `json:"start"` + + // End is the position of first character immediately after the spec or container block + End int `json:"end"` + + Spec bool `json:"spec"` + Focused bool `json:"focused"` + Pending bool `json:"pending"` +} + +// ginkgoNode is used to construct the outline as a tree +type ginkgoNode struct { + ginkgoMetadata + Nodes []*ginkgoNode `json:"nodes"` +} + +type walkFunc func(n *ginkgoNode) + +func (n *ginkgoNode) PreOrder(f walkFunc) { + f(n) + for _, m := range n.Nodes { + m.PreOrder(f) + } +} + +func (n *ginkgoNode) PostOrder(f walkFunc) { + for _, m := range n.Nodes { + m.PostOrder(f) + } + f(n) +} + +func (n *ginkgoNode) Walk(pre, post walkFunc) { + pre(n) + for _, m := range n.Nodes { + m.Walk(pre, post) + } + post(n) +} + +// PropagateInheritedProperties propagates the Pending and Focused properties +// through the subtree rooted at n. +func (n *ginkgoNode) PropagateInheritedProperties() { + n.PreOrder(func(thisNode *ginkgoNode) { + for _, descendantNode := range thisNode.Nodes { + if thisNode.Pending { + descendantNode.Pending = true + descendantNode.Focused = false + } + if thisNode.Focused && !descendantNode.Pending { + descendantNode.Focused = true + } + } + }) +} + +// BackpropagateUnfocus propagates the Focused property through the subtree +// rooted at n. It applies the rule described in the Ginkgo docs: +// > Nested programmatically focused specs follow a simple rule: if a +// > leaf-node is marked focused, any of its ancestor nodes that are marked +// > focus will be unfocused. +func (n *ginkgoNode) BackpropagateUnfocus() { + focusedSpecInSubtreeStack := []bool{} + n.PostOrder(func(thisNode *ginkgoNode) { + if thisNode.Spec { + focusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, thisNode.Focused) + return + } + focusedSpecInSubtree := false + for range thisNode.Nodes { + focusedSpecInSubtree = focusedSpecInSubtree || focusedSpecInSubtreeStack[len(focusedSpecInSubtreeStack)-1] + focusedSpecInSubtreeStack = focusedSpecInSubtreeStack[0 : len(focusedSpecInSubtreeStack)-1] + } + focusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, focusedSpecInSubtree) + if focusedSpecInSubtree { + thisNode.Focused = false + } + }) + +} + +func packageAndIdentNamesFromCallExpr(ce *ast.CallExpr) (string, string, bool) { + switch ex := ce.Fun.(type) { + case *ast.Ident: + return "", ex.Name, true + case *ast.SelectorExpr: + pkgID, ok := ex.X.(*ast.Ident) + if !ok { + return "", "", false + } + // A package identifier is top-level, so Obj must be nil + if pkgID.Obj != nil { + return "", "", false + } + if ex.Sel == nil { + return "", "", false + } + return pkgID.Name, ex.Sel.Name, true + default: + return "", "", false + } +} + +// absoluteOffsetsForNode derives the absolute character offsets of the node start and +// end positions. +func absoluteOffsetsForNode(fset *token.FileSet, n ast.Node) (start, end int) { + return fset.PositionFor(n.Pos(), false).Offset, fset.PositionFor(n.End(), false).Offset +} + +// ginkgoNodeFromCallExpr derives an outline entry from a go AST subtree +// corresponding to a Ginkgo container or spec. +func ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackageName, tablePackageName *string) (*ginkgoNode, bool) { + packageName, identName, ok := packageAndIdentNamesFromCallExpr(ce) + if !ok { + return nil, false + } + + n := ginkgoNode{} + n.Name = identName + n.Start, n.End = absoluteOffsetsForNode(fset, ce) + n.Nodes = make([]*ginkgoNode, 0) + switch identName { + case "It", "Measure", "Specify": + n.Spec = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "Entry": + n.Spec = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, tablePackageName != nil && *tablePackageName == packageName + case "FIt", "FMeasure", "FSpecify": + n.Spec = true + n.Focused = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "FEntry": + n.Spec = true + n.Focused = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, tablePackageName != nil && *tablePackageName == packageName + case "PIt", "PMeasure", "PSpecify", "XIt", "XMeasure", "XSpecify": + n.Spec = true + n.Pending = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "PEntry", "XEntry": + n.Spec = true + n.Pending = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, tablePackageName != nil && *tablePackageName == packageName + case "Context", "Describe", "When": + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "DescribeTable": + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, tablePackageName != nil && *tablePackageName == packageName + case "FContext", "FDescribe", "FWhen": + n.Focused = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "FDescribeTable": + n.Focused = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, tablePackageName != nil && *tablePackageName == packageName + case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen": + n.Pending = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "PDescribeTable", "XDescribeTable": + n.Pending = true + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, tablePackageName != nil && *tablePackageName == packageName + case "By": + n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "AfterEach", "BeforeEach": + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "JustAfterEach", "JustBeforeEach": + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "AfterSuite", "BeforeSuite": + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + case "SynchronizedAfterSuite", "SynchronizedBeforeSuite": + return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName + default: + return nil, false + } +} + +// textOrAltFromCallExpr tries to derive the "text" of a Ginkgo spec or +// container. If it cannot derive it, it returns the alt text. +func textOrAltFromCallExpr(ce *ast.CallExpr, alt string) string { + text, defined := textFromCallExpr(ce) + if !defined { + return alt + } + return text +} + +// textFromCallExpr tries to derive the "text" of a Ginkgo spec or container. If +// it cannot derive it, it returns false. +func textFromCallExpr(ce *ast.CallExpr) (string, bool) { + if len(ce.Args) < 1 { + return "", false + } + text, ok := ce.Args[0].(*ast.BasicLit) + if !ok { + return "", false + } + switch text.Kind { + case token.CHAR, token.STRING: + // For token.CHAR and token.STRING, Value is quoted + unquoted, err := strconv.Unquote(text.Value) + if err != nil { + // If unquoting fails, just use the raw Value + return text.Value, true + } + return unquoted, true + default: + return text.Value, true + } +} diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/outline/import.go b/vendor/github.com/onsi/ginkgo/ginkgo/outline/import.go new file mode 100644 index 000000000..4328ab391 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/ginkgo/outline/import.go @@ -0,0 +1,65 @@ +// Copyright 2013 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. + +// Most of the required functions were available in the +// "golang.org/x/tools/go/ast/astutil" package, but not exported. +// They were copied from https://github.com/golang/tools/blob/2b0845dc783e36ae26d683f4915a5840ef01ab0f/go/ast/astutil/imports.go + +package outline + +import ( + "go/ast" + "strconv" + "strings" +) + +// packageNameForImport returns the package name for the package. If the package +// is not imported, it returns nil. "Package name" refers to `pkgname` in the +// call expression `pkgname.ExportedIdentifier`. Examples: +// (import path not found) -> nil +// "import example.com/pkg/foo" -> "foo" +// "import fooalias example.com/pkg/foo" -> "fooalias" +// "import . example.com/pkg/foo" -> "" +func packageNameForImport(f *ast.File, path string) *string { + spec := importSpec(f, path) + if spec == nil { + return nil + } + name := spec.Name.String() + if name == "" { + // If the package name is not explicitly specified, + // make an educated guess. This is not guaranteed to be correct. + lastSlash := strings.LastIndex(path, "/") + if lastSlash == -1 { + name = path + } else { + name = path[lastSlash+1:] + } + } + if name == "." { + name = "" + } + return &name +} + +// importSpec returns the import spec if f imports path, +// or nil otherwise. +func importSpec(f *ast.File, path string) *ast.ImportSpec { + for _, s := range f.Imports { + if importPath(s) == path { + return s + } + } + return nil +} + +// importPath returns the unquoted import path of s, +// or "" if the path is not properly quoted. +func importPath(s *ast.ImportSpec) string { + t, err := strconv.Unquote(s.Path.Value) + if err != nil { + return "" + } + return t +} diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/outline/outline.go b/vendor/github.com/onsi/ginkgo/ginkgo/outline/outline.go new file mode 100644 index 000000000..242e6a109 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/ginkgo/outline/outline.go @@ -0,0 +1,107 @@ +package outline + +import ( + "encoding/json" + "fmt" + "go/ast" + "go/token" + "strings" + + "golang.org/x/tools/go/ast/inspector" +) + +const ( + // ginkgoImportPath is the well-known ginkgo import path + ginkgoImportPath = "github.com/onsi/ginkgo" + + // tableImportPath is the well-known table extension import path + tableImportPath = "github.com/onsi/ginkgo/extensions/table" +) + +// FromASTFile returns an outline for a Ginkgo test source file +func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) { + ginkgoPackageName := packageNameForImport(src, ginkgoImportPath) + tablePackageName := packageNameForImport(src, tableImportPath) + if ginkgoPackageName == nil && tablePackageName == nil { + return nil, fmt.Errorf("file does not import %q or %q", ginkgoImportPath, tableImportPath) + } + + root := ginkgoNode{} + stack := []*ginkgoNode{&root} + ispr := inspector.New([]*ast.File{src}) + ispr.Nodes([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool) bool { + if push { + // Pre-order traversal + ce, ok := node.(*ast.CallExpr) + if !ok { + // Because `Nodes` calls this function only when the node is an + // ast.CallExpr, this should never happen + panic(fmt.Errorf("node starting at %d, ending at %d is not an *ast.CallExpr", node.Pos(), node.End())) + } + gn, ok := ginkgoNodeFromCallExpr(fset, ce, ginkgoPackageName, tablePackageName) + if !ok { + // Node is not a Ginkgo spec or container, continue + return true + } + parent := stack[len(stack)-1] + parent.Nodes = append(parent.Nodes, gn) + stack = append(stack, gn) + return true + } + // Post-order traversal + start, end := absoluteOffsetsForNode(fset, node) + lastVisitedGinkgoNode := stack[len(stack)-1] + if start != lastVisitedGinkgoNode.Start || end != lastVisitedGinkgoNode.End { + // Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue + return true + } + stack = stack[0 : len(stack)-1] + return true + }) + if len(root.Nodes) == 0 { + return &outline{[]*ginkgoNode{}}, nil + } + + // Derive the final focused property for all nodes. This must be done + // _before_ propagating the inherited focused property. + root.BackpropagateUnfocus() + // Now, propagate inherited properties, including focused and pending. + root.PropagateInheritedProperties() + + return &outline{root.Nodes}, nil +} + +type outline struct { + Nodes []*ginkgoNode `json:"nodes"` +} + +func (o *outline) MarshalJSON() ([]byte, error) { + return json.Marshal(o.Nodes) +} + +// String returns a CSV-formatted outline. Spec or container are output in +// depth-first order. +func (o *outline) String() string { + return o.StringIndent(0) +} + +// StringIndent returns a CSV-formated outline, but every line is indented by +// one 'width' of spaces for every level of nesting. +func (o *outline) StringIndent(width int) string { + var b strings.Builder + b.WriteString("Name,Text,Start,End,Spec,Focused,Pending\n") + + currentIndent := 0 + pre := func(n *ginkgoNode) { + b.WriteString(fmt.Sprintf("%*s", currentIndent, "")) + b.WriteString(fmt.Sprintf("%s,%s,%d,%d,%t,%t,%t\n", n.Name, n.Text, n.Start, n.End, n.Spec, n.Focused, n.Pending)) + currentIndent += width + } + post := func(n *ginkgoNode) { + currentIndent -= width + } + for _, n := range o.Nodes { + n.Walk(pre, post) + } + return b.String() +} diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/outline_command.go b/vendor/github.com/onsi/ginkgo/ginkgo/outline_command.go new file mode 100644 index 000000000..96ca7ad27 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/ginkgo/outline_command.go @@ -0,0 +1,95 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "go/parser" + "go/token" + "os" + + "github.com/onsi/ginkgo/ginkgo/outline" +) + +const ( + // indentWidth is the width used by the 'indent' output + indentWidth = 4 + // stdinAlias is a portable alias for stdin. This convention is used in + // other CLIs, e.g., kubectl. + stdinAlias = "-" + usageCommand = "ginkgo outline " +) + +func BuildOutlineCommand() *Command { + const defaultFormat = "csv" + var format string + flagSet := flag.NewFlagSet("outline", flag.ExitOnError) + flagSet.StringVar(&format, "format", defaultFormat, "Format of outline. Accepted: 'csv', 'indent', 'json'") + return &Command{ + Name: "outline", + FlagSet: flagSet, + UsageCommand: usageCommand, + Usage: []string{ + "Create an outline of Ginkgo symbols for a file", + "To read from stdin, use: `ginkgo outline -`", + "Accepts the following flags:", + }, + Command: func(args []string, additionalArgs []string) { + outlineFile(args, format) + }, + } +} + +func outlineFile(args []string, format string) { + if len(args) != 1 { + println(fmt.Sprintf("usage: %s", usageCommand)) + os.Exit(1) + } + + filename := args[0] + var src *os.File + if filename == stdinAlias { + src = os.Stdin + } else { + var err error + src, err = os.Open(filename) + if err != nil { + println(fmt.Sprintf("error opening file: %s", err)) + os.Exit(1) + } + } + + fset := token.NewFileSet() + + parsedSrc, err := parser.ParseFile(fset, filename, src, 0) + if err != nil { + println(fmt.Sprintf("error parsing source: %s", err)) + os.Exit(1) + } + + o, err := outline.FromASTFile(fset, parsedSrc) + if err != nil { + println(fmt.Sprintf("error creating outline: %s", err)) + os.Exit(1) + } + + var oerr error + switch format { + case "csv": + _, oerr = fmt.Print(o) + case "indent": + _, oerr = fmt.Print(o.StringIndent(indentWidth)) + case "json": + b, err := json.Marshal(o) + if err != nil { + println(fmt.Sprintf("error marshalling to json: %s", err)) + } + _, oerr = fmt.Println(string(b)) + default: + complainAndQuit(fmt.Sprintf("format %s not accepted", format)) + } + if oerr != nil { + println(fmt.Sprintf("error writing outline: %s", oerr)) + os.Exit(1) + } +} diff --git a/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go b/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go index 30ff86f59..7e8a48708 100644 --- a/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go +++ b/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go @@ -93,26 +93,36 @@ func GinkgoT(optionalOffset ...int) GinkgoTInterface { if len(optionalOffset) > 0 { offset = optionalOffset[0] } - return testingtproxy.New(GinkgoWriter, Fail, offset) + failedFunc := func() bool { + return CurrentGinkgoTestDescription().Failed + } + nameFunc := func() string { + return CurrentGinkgoTestDescription().FullTestText + } + return testingtproxy.New(GinkgoWriter, Fail, Skip, failedFunc, nameFunc, offset) } //The interface returned by GinkgoT(). This covers most of the methods //in the testing package's T. type GinkgoTInterface interface { - Fail() + Cleanup(func()) Error(args ...interface{}) Errorf(format string, args ...interface{}) + Fail() FailNow() + Failed() bool Fatal(args ...interface{}) Fatalf(format string, args ...interface{}) + Helper() Log(args ...interface{}) Logf(format string, args ...interface{}) - Failed() bool + Name() string Parallel() Skip(args ...interface{}) - Skipf(format string, args ...interface{}) SkipNow() + Skipf(format string, args ...interface{}) Skipped() bool + TempDir() string } //Custom Ginkgo test reporters must implement the Reporter interface. diff --git a/vendor/github.com/onsi/ginkgo/go.mod b/vendor/github.com/onsi/ginkgo/go.mod index 1f7125228..655060cf7 100644 --- a/vendor/github.com/onsi/ginkgo/go.mod +++ b/vendor/github.com/onsi/ginkgo/go.mod @@ -4,8 +4,8 @@ require ( github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/nxadm/tail v1.4.4 github.com/onsi/gomega v1.10.1 - golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 - golang.org/x/text v0.3.2 // indirect + golang.org/x/sys v0.0.0-20210112080510-489259a85091 + golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e ) go 1.13 diff --git a/vendor/github.com/onsi/ginkgo/go.sum b/vendor/github.com/onsi/ginkgo/go.sum index 2b774f3e8..56a493f9d 100644 --- a/vendor/github.com/onsi/ginkgo/go.sum +++ b/vendor/github.com/onsi/ginkgo/go.sum @@ -1,8 +1,6 @@ -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -15,39 +13,50 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -57,11 +66,9 @@ google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyz google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_darwin.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_darwin.go deleted file mode 100644 index e3d09eadb..000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_darwin.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build darwin - -package remote - -import ( - "golang.org/x/sys/unix" -) - -func interceptorDupx(oldfd int, newfd int) { - unix.Dup2(oldfd, newfd) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_dragonfly.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_dragonfly.go deleted file mode 100644 index 72d38686a..000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_dragonfly.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build dragonfly - -package remote - -import ( - "golang.org/x/sys/unix" -) - -func interceptorDupx(oldfd int, newfd int) { - unix.Dup2(oldfd, newfd) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_freebsd.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_freebsd.go deleted file mode 100644 index 497d548d9..000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_freebsd.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build freebsd - -package remote - -import ( - "golang.org/x/sys/unix" -) - -func interceptorDupx(oldfd int, newfd int) { - unix.Dup2(oldfd, newfd) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux.go deleted file mode 100644 index 29add0d33..000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build linux -// +build !mips64le - -package remote - -import ( - "golang.org/x/sys/unix" -) - -func interceptorDupx(oldfd int, newfd int) { - unix.Dup2(oldfd, newfd) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux_mips64le.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux_mips64le.go deleted file mode 100644 index 09bd06260..000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_linux_mips64le.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build linux -// +build mips64le - -package remote - -import ( - "golang.org/x/sys/unix" -) - -func interceptorDupx(oldfd int, newfd int) { - unix.Dup3(oldfd, newfd, 0) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_netbsd.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_netbsd.go deleted file mode 100644 index 16ad6aeb2..000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_netbsd.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build netbsd - -package remote - -import ( - "golang.org/x/sys/unix" -) - -func interceptorDupx(oldfd int, newfd int) { - unix.Dup2(oldfd, newfd) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_openbsd.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_openbsd.go deleted file mode 100644 index 4275f8421..000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_openbsd.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build openbsd - -package remote - -import ( - "golang.org/x/sys/unix" -) - -func interceptorDupx(oldfd int, newfd int) { - unix.Dup2(oldfd, newfd) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_solaris.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_solaris.go deleted file mode 100644 index 882a38a9e..000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_solaris.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build solaris - -package remote - -import ( - "golang.org/x/sys/unix" -) - -func interceptorDupx(oldfd int, newfd int) { - unix.Dup2(oldfd, newfd) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go index 80614d0ce..774967db6 100644 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go +++ b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go @@ -8,6 +8,7 @@ import ( "os" "github.com/nxadm/tail" + "golang.org/x/sys/unix" ) func NewOutputInterceptor() OutputInterceptor { @@ -35,8 +36,10 @@ func (interceptor *outputInterceptor) StartInterceptingOutput() error { return err } - interceptorDupx(int(interceptor.redirectFile.Fd()), 1) - interceptorDupx(int(interceptor.redirectFile.Fd()), 2) + // This might call Dup3 if the dup2 syscall is not available, e.g. on + // linux/arm64 or linux/riscv64 + unix.Dup2(int(interceptor.redirectFile.Fd()), 1) + unix.Dup2(int(interceptor.redirectFile.Fd()), 2) if interceptor.streamTarget != nil { interceptor.tailer, _ = tail.TailFile(interceptor.redirectFile.Name(), tail.Config{Follow: true}) diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/specs.go b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go index 8a2007137..0a24139fb 100644 --- a/vendor/github.com/onsi/ginkgo/internal/spec/specs.go +++ b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go @@ -4,6 +4,7 @@ import ( "math/rand" "regexp" "sort" + "strings" ) type Specs struct { @@ -46,11 +47,11 @@ func (e *Specs) Shuffle(r *rand.Rand) { e.names = names } -func (e *Specs) ApplyFocus(description string, focusString string, skipString string) { - if focusString == "" && skipString == "" { +func (e *Specs) ApplyFocus(description string, focus, skip []string) { + if len(focus)+len(skip) == 0 { e.applyProgrammaticFocus() } else { - e.applyRegExpFocusAndSkip(description, focusString, skipString) + e.applyRegExpFocusAndSkip(description, focus, skip) } } @@ -90,14 +91,13 @@ func (e *Specs) toMatch(description string, i int) []byte { } } -func (e *Specs) applyRegExpFocusAndSkip(description string, focusString string, skipString string) { - var focusFilter *regexp.Regexp - if focusString != "" { - focusFilter = regexp.MustCompile(focusString) +func (e *Specs) applyRegExpFocusAndSkip(description string, focus, skip []string) { + var focusFilter, skipFilter *regexp.Regexp + if len(focus) > 0 { + focusFilter = regexp.MustCompile(strings.Join(focus, "|")) } - var skipFilter *regexp.Regexp - if skipString != "" { - skipFilter = regexp.MustCompile(skipString) + if len(skip) > 0 { + skipFilter = regexp.MustCompile(strings.Join(skip, "|")) } for i, spec := range e.specs { diff --git a/vendor/github.com/onsi/ginkgo/internal/suite/suite.go b/vendor/github.com/onsi/ginkgo/internal/suite/suite.go index e75da1f89..b4a83c432 100644 --- a/vendor/github.com/onsi/ginkgo/internal/suite/suite.go +++ b/vendor/github.com/onsi/ginkgo/internal/suite/suite.go @@ -97,7 +97,7 @@ func (suite *Suite) generateSpecsIterator(description string, config config.Gink specs.Shuffle(rand.New(rand.NewSource(config.RandomSeed))) } - specs.ApplyFocus(description, config.FocusString, config.SkipString) + specs.ApplyFocus(description, config.FocusStrings, config.SkipStrings) if config.SkipMeasurements { specs.SkipMeasurements() diff --git a/vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go b/vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go index 090445d08..d7bbb7a96 100644 --- a/vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go +++ b/vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go @@ -6,21 +6,34 @@ import ( ) type failFunc func(message string, callerSkip ...int) +type skipFunc func(message string, callerSkip ...int) +type failedFunc func() bool +type nameFunc func() string -func New(writer io.Writer, fail failFunc, offset int) *ginkgoTestingTProxy { +func New(writer io.Writer, fail failFunc, skip skipFunc, failed failedFunc, name nameFunc, offset int) *ginkgoTestingTProxy { return &ginkgoTestingTProxy{ fail: fail, offset: offset, writer: writer, + skip: skip, + failed: failed, + name: name, } } type ginkgoTestingTProxy struct { fail failFunc + skip skipFunc + failed failedFunc + name nameFunc offset int writer io.Writer } +func (t *ginkgoTestingTProxy) Cleanup(func()) { + // No-op +} + func (t *ginkgoTestingTProxy) Error(args ...interface{}) { t.fail(fmt.Sprintln(args...), t.offset) } @@ -37,6 +50,10 @@ func (t *ginkgoTestingTProxy) FailNow() { t.fail("failed", t.offset) } +func (t *ginkgoTestingTProxy) Failed() bool { + return t.failed() +} + func (t *ginkgoTestingTProxy) Fatal(args ...interface{}) { t.fail(fmt.Sprintln(args...), t.offset) } @@ -45,6 +62,10 @@ func (t *ginkgoTestingTProxy) Fatalf(format string, args ...interface{}) { t.fail(fmt.Sprintf(format, args...), t.offset) } +func (t *ginkgoTestingTProxy) Helper() { + // No-op +} + func (t *ginkgoTestingTProxy) Log(args ...interface{}) { fmt.Fprintln(t.writer, args...) } @@ -53,24 +74,31 @@ func (t *ginkgoTestingTProxy) Logf(format string, args ...interface{}) { t.Log(fmt.Sprintf(format, args...)) } -func (t *ginkgoTestingTProxy) Failed() bool { - return false +func (t *ginkgoTestingTProxy) Name() string { + return t.name() } func (t *ginkgoTestingTProxy) Parallel() { + // No-op } func (t *ginkgoTestingTProxy) Skip(args ...interface{}) { - fmt.Println(args...) + t.skip(fmt.Sprintln(args...), t.offset) } -func (t *ginkgoTestingTProxy) Skipf(format string, args ...interface{}) { - t.Skip(fmt.Sprintf(format, args...)) +func (t *ginkgoTestingTProxy) SkipNow() { + t.skip("skip", t.offset) } -func (t *ginkgoTestingTProxy) SkipNow() { +func (t *ginkgoTestingTProxy) Skipf(format string, args ...interface{}) { + t.skip(fmt.Sprintf(format, args...), t.offset) } func (t *ginkgoTestingTProxy) Skipped() bool { return false } + +func (t *ginkgoTestingTProxy) TempDir() string { + // No-op + return "" +} diff --git a/vendor/github.com/onsi/gomega/.travis.yml b/vendor/github.com/onsi/gomega/.travis.yml index 072fdd2db..348e3014c 100644 --- a/vendor/github.com/onsi/gomega/.travis.yml +++ b/vendor/github.com/onsi/gomega/.travis.yml @@ -1,8 +1,11 @@ language: go +arch: + - amd64 + - ppc64le go: - - 1.13.x - 1.14.x + - 1.15.x - gotip env: diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 3aafdbcfc..16095fa3c 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,27 @@ +## 1.10.5 + +### Fixes +- fix: collections matchers should display type of expectation (#408) [6b4eb5a] +- fix(ContainElements): consistently flatten expected values [073b880] +- fix(ConsistOf): consistently flatten expected values [7266efe] + +## 1.10.4 + +### Fixes +- update golang net library to more recent version without vulnerability (#406) [817a8b9] +- Correct spelling: alloted -> allotted (#403) [0bae715] +- fix a panic in MessageWithDiff with long message (#402) [ea06b9b] + +## 1.10.3 + +### Fixes +- updates golang/x/net to fix vulnerability detected by snyk (#394) [c479356] + +## 1.10.2 + +### Fixes +- Add ExpectWithOffset, EventuallyWithOffset and ConsistentlyWithOffset to WithT (#391) [990941a] + ## 1.10.1 ### Fixes diff --git a/vendor/github.com/onsi/gomega/format/format.go b/vendor/github.com/onsi/gomega/format/format.go index fae25adce..e59d7d75b 100644 --- a/vendor/github.com/onsi/gomega/format/format.go +++ b/vendor/github.com/onsi/gomega/format/format.go @@ -105,7 +105,13 @@ func MessageWithDiff(actual, message, expected string) string { tabLength := 4 spaceFromMessageToActual := tabLength + len(": ") - len(message) - padding := strings.Repeat(" ", spaceFromMessageToActual+spacesBeforeFormattedMismatch) + "|" + + paddingCount := spaceFromMessageToActual + spacesBeforeFormattedMismatch + if paddingCount < 0 { + return Message(formattedActual, message, formattedExpected) + } + + padding := strings.Repeat(" ", paddingCount) + "|" return Message(formattedActual, message+padding, formattedExpected) } diff --git a/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go b/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go index 3caed8769..a41ad6232 100644 --- a/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go +++ b/vendor/github.com/onsi/gomega/gbytes/io_wrappers.go @@ -9,17 +9,17 @@ import ( // ErrTimeout is returned by TimeoutCloser, TimeoutReader, and TimeoutWriter when the underlying Closer/Reader/Writer does not return within the specified timeout var ErrTimeout = errors.New("timeout occurred") -// TimeoutCloser returns an io.Closer that wraps the passed-in io.Closer. If the underlying Closer fails to close within the alloted timeout ErrTimeout is returned. +// TimeoutCloser returns an io.Closer that wraps the passed-in io.Closer. If the underlying Closer fails to close within the allotted timeout ErrTimeout is returned. func TimeoutCloser(c io.Closer, timeout time.Duration) io.Closer { return timeoutReaderWriterCloser{c: c, d: timeout} } -// TimeoutReader returns an io.Reader that wraps the passed-in io.Reader. If the underlying Reader fails to read within the alloted timeout ErrTimeout is returned. +// TimeoutReader returns an io.Reader that wraps the passed-in io.Reader. If the underlying Reader fails to read within the allotted timeout ErrTimeout is returned. func TimeoutReader(r io.Reader, timeout time.Duration) io.Reader { return timeoutReaderWriterCloser{r: r, d: timeout} } -// TimeoutWriter returns an io.Writer that wraps the passed-in io.Writer. If the underlying Writer fails to write within the alloted timeout ErrTimeout is returned. +// TimeoutWriter returns an io.Writer that wraps the passed-in io.Writer. If the underlying Writer fails to write within the allotted timeout ErrTimeout is returned. func TimeoutWriter(w io.Writer, timeout time.Duration) io.Writer { return timeoutReaderWriterCloser{w: w, d: timeout} } diff --git a/vendor/github.com/onsi/gomega/go.mod b/vendor/github.com/onsi/gomega/go.mod index 778935141..6f853a579 100644 --- a/vendor/github.com/onsi/gomega/go.mod +++ b/vendor/github.com/onsi/gomega/go.mod @@ -1,9 +1,10 @@ module github.com/onsi/gomega +go 1.14 + require ( github.com/golang/protobuf v1.4.2 github.com/onsi/ginkgo v1.12.1 - golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 - golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 + golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb gopkg.in/yaml.v2 v2.3.0 ) diff --git a/vendor/github.com/onsi/gomega/go.sum b/vendor/github.com/onsi/gomega/go.sum index 610b09bee..54eeacd2b 100644 --- a/vendor/github.com/onsi/gomega/go.sum +++ b/vendor/github.com/onsi/gomega/go.sum @@ -23,22 +23,28 @@ github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index 8ff9611d5..1bc5288b8 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -24,7 +24,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.10.1" +const GOMEGA_VERSION = "1.10.5" const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil. If you're using Ginkgo then you probably forgot to put your assertion in an It(). @@ -376,13 +376,13 @@ func NewGomegaWithT(t types.GomegaTestingT) *GomegaWithT { return NewWithT(t) } -// Expect is used to make assertions. See documentation for Expect. -func (g *WithT) Expect(actual interface{}, extra ...interface{}) Assertion { - return assertion.New(actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), 0, extra...) +// ExpectWithOffset is used to make assertions. See documentation for ExpectWithOffset. +func (g *WithT) ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Assertion { + return assertion.New(actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), offset, extra...) } -// Eventually is used to make asynchronous assertions. See documentation for Eventually. -func (g *WithT) Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { +// EventuallyWithOffset is used to make asynchronous assertions. See documentation for EventuallyWithOffset. +func (g *WithT) EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { timeoutInterval := defaultEventuallyTimeout pollingInterval := defaultEventuallyPollingInterval if len(intervals) > 0 { @@ -391,11 +391,11 @@ func (g *WithT) Eventually(actual interface{}, intervals ...interface{}) AsyncAs if len(intervals) > 1 { pollingInterval = toDuration(intervals[1]) } - return asyncassertion.New(asyncassertion.AsyncAssertionTypeEventually, actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), timeoutInterval, pollingInterval, 0) + return asyncassertion.New(asyncassertion.AsyncAssertionTypeEventually, actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), timeoutInterval, pollingInterval, offset) } -// Consistently is used to make asynchronous assertions. See documentation for Consistently. -func (g *WithT) Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { +// ConsistentlyWithOffset is used to make asynchronous assertions. See documentation for ConsistentlyWithOffset. +func (g *WithT) ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { timeoutInterval := defaultConsistentlyDuration pollingInterval := defaultConsistentlyPollingInterval if len(intervals) > 0 { @@ -404,7 +404,22 @@ func (g *WithT) Consistently(actual interface{}, intervals ...interface{}) Async if len(intervals) > 1 { pollingInterval = toDuration(intervals[1]) } - return asyncassertion.New(asyncassertion.AsyncAssertionTypeConsistently, actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), timeoutInterval, pollingInterval, 0) + return asyncassertion.New(asyncassertion.AsyncAssertionTypeConsistently, actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), timeoutInterval, pollingInterval, offset) +} + +// Expect is used to make assertions. See documentation for Expect. +func (g *WithT) Expect(actual interface{}, extra ...interface{}) Assertion { + return g.ExpectWithOffset(0, actual, extra...) +} + +// Eventually is used to make asynchronous assertions. See documentation for Eventually. +func (g *WithT) Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { + return g.EventuallyWithOffset(0, actual, intervals...) +} + +// Consistently is used to make asynchronous assertions. See documentation for Consistently. +func (g *WithT) Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { + return g.ConsistentlyWithOffset(0, actual, intervals...) } func toDuration(input interface{}) time.Duration { diff --git a/vendor/github.com/onsi/gomega/matchers/consist_of.go b/vendor/github.com/onsi/gomega/matchers/consist_of.go index e453b22d1..e8ef0dee1 100644 --- a/vendor/github.com/onsi/gomega/matchers/consist_of.go +++ b/vendor/github.com/onsi/gomega/matchers/consist_of.go @@ -57,17 +57,21 @@ func equalMatchersToElements(matchers []interface{}) (elements []interface{}) { return } -func matchers(expectedElems []interface{}) (matchers []interface{}) { - elems := expectedElems - if len(expectedElems) == 1 && isArrayOrSlice(expectedElems[0]) { - elems = []interface{}{} - value := reflect.ValueOf(expectedElems[0]) - for i := 0; i < value.Len(); i++ { - elems = append(elems, value.Index(i).Interface()) - } +func flatten(elems []interface{}) []interface{} { + if len(elems) != 1 || !isArrayOrSlice(elems[0]) { + return elems } - for _, e := range elems { + value := reflect.ValueOf(elems[0]) + flattened := make([]interface{}, value.Len()) + for i := 0; i < value.Len(); i++ { + flattened[i] = value.Index(i).Interface() + } + return flattened +} + +func matchers(expectedElems []interface{}) (matchers []interface{}) { + for _, e := range flatten(expectedElems) { matcher, isMatcher := e.(omegaMatcher) if !isMatcher { matcher = &EqualMatcher{Expected: e} @@ -77,6 +81,29 @@ func matchers(expectedElems []interface{}) (matchers []interface{}) { return } +func presentable(elems []interface{}) interface{} { + elems = flatten(elems) + + if len(elems) == 0 { + return []interface{}{} + } + + sv := reflect.ValueOf(elems) + tt := sv.Index(0).Elem().Type() + for i := 1; i < sv.Len(); i++ { + if sv.Index(i).Elem().Type() != tt { + return elems + } + } + + ss := reflect.MakeSlice(reflect.SliceOf(tt), sv.Len(), sv.Len()) + for i := 0; i < sv.Len(); i++ { + ss.Index(i).Set(sv.Index(i).Elem()) + } + + return ss.Interface() +} + func valuesOf(actual interface{}) []interface{} { value := reflect.ValueOf(actual) values := []interface{}{} @@ -95,11 +122,11 @@ func valuesOf(actual interface{}) []interface{} { } func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) { - message = format.Message(actual, "to consist of", matcher.Elements) + message = format.Message(actual, "to consist of", presentable(matcher.Elements)) message = appendMissingElements(message, matcher.missingElements) if len(matcher.extraElements) > 0 { message = fmt.Sprintf("%s\nthe extra elements were\n%s", message, - format.Object(matcher.extraElements, 1)) + format.Object(presentable(matcher.extraElements), 1)) } return } @@ -109,9 +136,9 @@ func appendMissingElements(message string, missingElements []interface{}) string return message } return fmt.Sprintf("%s\nthe missing elements were\n%s", message, - format.Object(missingElements, 1)) + format.Object(presentable(missingElements), 1)) } func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return format.Message(actual, "not to consist of", matcher.Elements) + return format.Message(actual, "not to consist of", presentable(matcher.Elements)) } diff --git a/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go b/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go index 19a9e78f8..946cd8bea 100644 --- a/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go @@ -35,10 +35,10 @@ func (matcher *ContainElementsMatcher) Match(actual interface{}) (success bool, } func (matcher *ContainElementsMatcher) FailureMessage(actual interface{}) (message string) { - message = format.Message(actual, "to contain elements", matcher.Elements) + message = format.Message(actual, "to contain elements", presentable(matcher.Elements)) return appendMissingElements(message, matcher.missingElements) } func (matcher *ContainElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return format.Message(actual, "not to contain elements", matcher.Elements) + return format.Message(actual, "not to contain elements", presentable(matcher.Elements)) } diff --git a/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go index 4e09239ff..c8993a86d 100644 --- a/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go @@ -1,11 +1,11 @@ package matchers import ( + "errors" "fmt" "reflect" "github.com/onsi/gomega/format" - "golang.org/x/xerrors" ) type MatchErrorMatcher struct { @@ -25,7 +25,7 @@ func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err e expected := matcher.Expected if isError(expected) { - return reflect.DeepEqual(actualErr, expected) || xerrors.Is(actualErr, expected.(error)), nil + return reflect.DeepEqual(actualErr, expected) || errors.Is(actualErr, expected.(error)), nil } if isString(expected) { diff --git a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/cleanup.go b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/cleanup.go index 7ab391f77..4e2831163 100644 --- a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/cleanup.go +++ b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/cleanup.go @@ -5,38 +5,64 @@ import ( "fmt" "time" + "github.com/go-logr/logr" "github.com/pkg/errors" + corev1 "k8s.io/api/core/v1" + "github.com/qinqon/kube-admission-webhook/pkg/certificate/triple" ) -// earliestElapsedForCleanup return a subtraction between earliestCleanupDeadline and -// `now` -func (m *Manager) earliestElapsedForCleanup() (time.Duration, error) { - deadline, err := m.earliestCleanupDeadline() +func (m *Manager) earliestElapsedForCACertsCleanup() (time.Duration, error) { + cas, err := m.getCACertsFromCABundle() if err != nil { - return time.Duration(0), errors.Wrap(err, "failed calculating cleanup deadline") + return time.Duration(0), errors.Wrap(err, "failed getting CA certificates from CA bundle") } - now := m.now() - elapsedForCleanup := deadline.Sub(now) - m.log.Info(fmt.Sprintf("earliestElapsedForCleanup {now: %s, deadline: %s, elapsedForCleanup: %s}", now, deadline, elapsedForCleanup)) - return elapsedForCleanup, nil + return m.earliestElapsedForCleanup(m.log.WithName("earliestElapsedForCACertsCleanup"), cas) } -// earliestCleanupDeadline get all the certificates at CABundle and return the -// deadline calculated by earliestCleanupDeadlineForCerts -func (m *Manager) earliestCleanupDeadline() (time.Time, error) { - cas, err := m.getCACertsFromCABundle() +// earliestElapsedForServiceCertsCleanup will iterate all the services and +// retrieve the secrets associate, calculate the elapsed time for +// cleanup for each and return the min. +func (m *Manager) earliestElapsedForServiceCertsCleanup() (time.Duration, error) { + webhookConf, err := m.readyWebhookConfiguration() if err != nil { - return m.now(), errors.Wrap(err, "failed getting CA certificates from CA bundle") + return time.Duration(0), fmt.Errorf("failed getting webhook configuration to calculate cleanup next run: %w", err) } - return m.earliestCleanupDeadlineForCerts(cas), nil + services, err := m.getServicesFromConfiguration(webhookConf) + if err != nil { + return time.Duration(0), fmt.Errorf("failed getting services to calculate cleanup next run: %w", err) + } + + elapsedTimesForCleanup := []time.Duration{} + for service, _ := range services { + + certs, err := m.getTLSCerts(service) + if err != nil { + return time.Duration(0), fmt.Errorf("failed getting TLS keypair from service %s to calculate cleanup next run: %w", service, err) + } + elapsedTimeForCleanup, err := m.earliestElapsedForCleanup(m.log.WithName("earliestElapsedForServiceCertsCleanup").WithValues("service", service), certs) + if err != nil { + return time.Duration(0), err + } + elapsedTimesForCleanup = append(elapsedTimesForCleanup, elapsedTimeForCleanup) + } + return min(elapsedTimesForCleanup...), nil +} + +// earliestElapsedForCleanup return a subtraction between earliestCleanupDeadline and +// `now` +func (m *Manager) earliestElapsedForCleanup(log logr.Logger, certificates []*x509.Certificate) (time.Duration, error) { + deadline := m.earliestCleanupDeadlineForCerts(certificates) + now := m.now() + elapsedForCleanup := deadline.Sub(now) + log.Info(fmt.Sprintf("{now: %s, deadline: %s, elapsedForCleanup: %s}", now, deadline, elapsedForCleanup)) + return elapsedForCleanup, nil } // earliestCleanupDeadlineForCACerts will inspect CA certificates -// select the deadline based on certificate NotBefore + caOverlapDuration -// returning the daedline that is going to happend sooner +// select the deadline based on expiration time func (m *Manager) earliestCleanupDeadlineForCerts(certificates []*x509.Certificate) time.Time { var selectedCertificate *x509.Certificate @@ -46,20 +72,18 @@ func (m *Manager) earliestCleanupDeadlineForCerts(certificates []*x509.Certifica } for _, certificate := range certificates { - if selectedCertificate == nil || certificate.NotBefore.Before(selectedCertificate.NotBefore) { + if selectedCertificate == nil || certificate.NotAfter.Before(selectedCertificate.NotAfter) { selectedCertificate = certificate } } if selectedCertificate == nil { return m.now() } - - // Add the overlap duration since is the time certs are going to be living - // add CABundle - return selectedCertificate.NotBefore.Add(m.caOverlapDuration) + return selectedCertificate.NotAfter } func (m *Manager) cleanUpCABundle() error { + m.log.Info("cleanUpCABundle") _, err := m.updateWebhookCABundleWithFunc(func([]byte) ([]byte, error) { cas, err := m.getCACertsFromCABundle() if err != nil { @@ -76,9 +100,41 @@ func (m *Manager) cleanUpCABundle() error { return nil } +func (m *Manager) cleanUpServiceCerts() error { + m.log.Info("cleanUpServiceCerts") + webhookConf, err := m.readyWebhookConfiguration() + if err != nil { + return fmt.Errorf("failed getting webhook configuration to do the cleanup: %w", err) + } + + services, err := m.getServicesFromConfiguration(webhookConf) + if err != nil { + return fmt.Errorf("failed getting services to do the cleanup: %w", err) + } + + for service, _ := range services { + m.applySecret(service, corev1.SecretTypeTLS, nil, func(secret corev1.Secret, keyPair *triple.KeyPair) (*corev1.Secret, error) { + certPEM, found := secret.Data[corev1.TLSCertKey] + if !found { + return nil, errors.Wrapf(err, "TLS cert not found at secret %s to clean up ", service) + } + + certs, err := triple.ParseCertsPEM(certPEM) + if err != nil { + return nil, errors.Wrapf(err, "failed parsing TLS cert PEM at secret %s to clean up", service) + } + + cleanedCerts := m.cleanUpCertificates(certs) + pem := triple.EncodeCertsPEM(cleanedCerts) + secret.Data[corev1.TLSCertKey] = pem + return &secret, nil + }) + } + return nil +} + func (m *Manager) cleanUpCertificates(certificates []*x509.Certificate) []*x509.Certificate { logger := m.log.WithName("cleanUpCertificates") - logger.Info("Cleaning up expired or beyond overlap duration limit at CA bundle") // There is no overlap if len(certificates) <= 1 { return certificates @@ -87,23 +143,16 @@ func (m *Manager) cleanUpCertificates(certificates []*x509.Certificate) []*x509. now := m.now() // create a zero-length slice with the same underlying array cleanedUpCertificates := certificates[:0] - for i, certificate := range certificates { - logger.Info("Checking certificate for cleanup", "now", now, "caOverlapDuration", m.caOverlapDuration, "NotBefore", certificate.NotBefore, "NotAfter", certificate.NotAfter) + for _, certificate := range certificates { + logger.Info("Checking certificate for cleanup", "now", now, "NotBefore", certificate.NotBefore, "NotAfter", certificate.NotAfter) // Expired certificate are cleaned up - caExpirationDate := certificate.NotAfter - if now.After(caExpirationDate) { + expirationDate := certificate.NotAfter + if now.Equal(expirationDate) || now.After(expirationDate) { logger.Info("Cleaning up expired certificate", "now", now, "NotBefore", certificate.NotBefore, "NotAfter", certificate.NotAfter) continue } - // Clean up certificates that pass CA Overlap Duration limit, - // except for the last appended one (i.e. the last generated from a rotation) since we need at least one valid certificate - caOverlapDate := certificate.NotBefore.Add(m.caOverlapDuration) - if i != len(certificates)-1 && !now.Before(caOverlapDate) { - logger.Info("Cleaning up certificate beyond CA overlap duration", "now", now, "caOverlapDuration", m.caOverlapDuration, "NotBefore", certificate.NotBefore, "NotAfter", certificate.NotAfter) - continue - } cleanedUpCertificates = append(cleanedUpCertificates, certificate) } return cleanedUpCertificates diff --git a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/configuration.go b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/configuration.go index 70af1ca50..b2efd5db8 100644 --- a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/configuration.go +++ b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/configuration.go @@ -83,16 +83,7 @@ func (m *Manager) readyWebhookConfiguration() (runtime.Object, error) { func (m *Manager) addCertificateToCABundle(caCert *x509.Certificate) error { m.log.Info("Reset CA bundle with one cert for webhook") _, err := m.updateWebhookCABundleWithFunc(func(currentCABundle []byte) ([]byte, error) { - cas := []*x509.Certificate{} - if len(currentCABundle) > 0 { - var err error - cas, err = triple.ParseCertsPEM(currentCABundle) - if err != nil { - return nil, errors.Wrap(err, "failed parsing current CA bundle") - } - } - cas = append(cas, caCert) - return triple.EncodeCertsPEM(cas), nil + return triple.AddCertToPEM(caCert, currentCABundle) }) if err != nil { return errors.Wrap(err, "failed to update webhook CABundle") @@ -151,7 +142,6 @@ func (m *Manager) CABundle() ([]byte, error) { // passing the url hostname at map value func (m *Manager) getServicesFromConfiguration(configuration runtime.Object) (map[types.NamespacedName][]string, error) { - logger := m.log.WithName("getServicesFromConfiguration") services := map[types.NamespacedName][]string{} for _, clientConfig := range m.clientConfigList(configuration) { @@ -160,11 +150,9 @@ func (m *Manager) getServicesFromConfiguration(configuration runtime.Object) (ma hostnames := []string{} if clientConfig.Service != nil { - logger.Info("Composing service name and namespace from ServiceRef", "serviceRef", clientConfig.Service) service.Name = clientConfig.Service.Name service.Namespace = clientConfig.Service.Namespace } else if clientConfig.URL != nil { - logger.Info("Composing service name and namespace from URL", "URL", clientConfig.URL) service.Name = m.webhookName service.Namespace = m.namespace u, err := url.Parse(*clientConfig.URL) diff --git a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/controller.go b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/controller.go index 829f748c3..955fc434f 100644 --- a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/controller.go +++ b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/controller.go @@ -85,7 +85,7 @@ func (m *Manager) add(mgr manager.Manager, r reconcile.Reconciler) error { // The Controller will requeue the Request to be processed again if the returned error is non-nil or // Result.Requeue is true, otherwise upon completion it will remove the work from the queue. func (m *Manager) Reconcile(request reconcile.Request) (reconcile.Result, error) { - reqLogger := m.log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name) + reqLogger := m.log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name).WithName("Reconcile") reqLogger.Info("Reconciling Certificates") elapsedToRotateCA := m.elapsedToRotateCAFromLastDeadline() @@ -114,7 +114,7 @@ func (m *Manager) Reconcile(request reconcile.Request) (reconcile.Result, error) // Re-calculate elapsedToRotate since we have generated new // certificates - m.nextRotationDeadline() + m.nextRotationDeadlineForCA() elapsedToRotateCA = m.elapsedToRotateCAFromLastDeadline() // Also recalculate it for serices certificate since they has changed @@ -123,7 +123,7 @@ func (m *Manager) Reconcile(request reconcile.Request) (reconcile.Result, error) } else if elapsedToRotateServices <= 0 { // CA is ok but expiration but we have passed expiration time for service certificates - err := m.rotateServices() + err := m.rotateServicesWithOverlap() if err != nil { return reconcile.Result{}, errors.Wrap(err, "failed rotating services certs") } @@ -134,29 +134,48 @@ func (m *Manager) Reconcile(request reconcile.Request) (reconcile.Result, error) elapsedToRotateServices = m.elapsedToRotateServicesFromLastDeadline() } - elapsedForCleanup, err := m.earliestElapsedForCleanup() + elapsedForCABundleCleanup, err := m.earliestElapsedForCACertsCleanup() if err != nil { - return reconcile.Result{}, errors.Wrap(err, "failed getting cleanup deadline") + return reconcile.Result{}, errors.Wrap(err, "failed getting ca bundle cleanup deadline") } // We have pass cleanup deadline let's do the cleanup - if elapsedForCleanup <= 0 { + if elapsedForCABundleCleanup <= 0 { err = m.cleanUpCABundle() if err != nil { return reconcile.Result{}, errors.Wrap(err, "failed cleaning up CABundle") } // Re-calculate cleanup deadline since we may have to remove some certs there - elapsedForCleanup, err = m.earliestElapsedForCleanup() + elapsedForCABundleCleanup, err = m.earliestElapsedForCACertsCleanup() if err != nil { - return reconcile.Result{}, errors.Wrap(err, "failed re-calculating cleanup deadline") + return reconcile.Result{}, errors.Wrap(err, "failed re-calculating ca bundle cleanup deadline") + } + } + + elapsedForServiceCertsCleanup, err := m.earliestElapsedForServiceCertsCleanup() + if err != nil { + return reconcile.Result{}, errors.Wrap(err, "failed getting service certs cleanup deadline") + } + + // We have pass cleanup deadline let's do the cleanup + if elapsedForServiceCertsCleanup <= 0 { + err = m.cleanUpServiceCerts() + if err != nil { + return reconcile.Result{}, errors.Wrap(err, "failed cleaning up service certs") + } + + // Re-calculate cleanup deadline since we may have to remove some certs there + elapsedForServiceCertsCleanup, err = m.earliestElapsedForServiceCertsCleanup() + if err != nil { + return reconcile.Result{}, errors.Wrap(err, "failed re-calculating service certs cleanup deadline") } } // Return the event that is going to happend sonner all services certificates rotation, // services certificate rotation or ca bundle cleanup - m.log.Info("Calculating RequeueAfter", "elapsedToRotateCA", elapsedToRotateCA, "elapsedToRotateServices", elapsedToRotateServices, "elapsedForCleanup", elapsedForCleanup) - requeueAfter := min(elapsedToRotateCA, elapsedToRotateServices, elapsedForCleanup) + m.log.Info("Calculating RequeueAfter", "elapsedToRotateCA", elapsedToRotateCA, "elapsedToRotateServices", elapsedToRotateServices, "elapsedForCABundleCleanup", elapsedForCABundleCleanup, "elapsedForServiceCertsCleanup", elapsedForServiceCertsCleanup) + requeueAfter := min(elapsedToRotateCA, elapsedToRotateServices, elapsedForCABundleCleanup, elapsedForServiceCertsCleanup) m.log.Info(fmt.Sprintf("Certificates will be Reconcile on %s", m.now().Add(requeueAfter))) return reconcile.Result{RequeueAfter: requeueAfter}, nil diff --git a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/manager.go b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/manager.go index 6b91836b6..f4c383a0d 100644 --- a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/manager.go +++ b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/manager.go @@ -10,7 +10,6 @@ import ( "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" @@ -54,6 +53,9 @@ type Manager struct { // serviceCertDuration Options.CertRotateInterval serviceCertDuration time.Duration + // serviceOverlapDuration Options.CertOverlapInterval + serviceOverlapDuration time.Duration + // log initialized log that containes the webhook configuration name and // namespace so it's easy to debug. log logr.Logger @@ -86,15 +88,16 @@ func NewManager( } m := &Manager{ - client: client, - webhookName: options.WebhookName, - webhookType: options.WebhookType, - namespace: options.Namespace, - now: time.Now, - caCertDuration: options.CARotateInterval, - caOverlapDuration: options.CAOverlapInterval, - serviceCertDuration: options.CertRotateInterval, - log: logf.Log.WithName("certificate/manager"). + client: client, + webhookName: options.WebhookName, + webhookType: options.WebhookType, + namespace: options.Namespace, + now: time.Now, + caCertDuration: options.CARotateInterval, + caOverlapDuration: options.CAOverlapInterval, + serviceCertDuration: options.CertRotateInterval, + serviceOverlapDuration: options.CertOverlapInterval, + log: logf.Log.WithName("certificate/Manager"). WithValues("webhookType", options.WebhookType, "webhookName", options.WebhookName), } return m, nil @@ -146,7 +149,8 @@ func (m *Manager) rotateAll() error { return errors.Wrap(err, "failed storing CA cert/key at secret") } - err = m.rotateServices() + // We have rotate the CA we need to reset the TLS removing previous certs + err = m.rotateServicesWithoutOverlap() if err != nil { return errors.Wrap(err, "failed rotating services") } @@ -154,7 +158,15 @@ func (m *Manager) rotateAll() error { return nil } -func (m *Manager) rotateServices() error { +func (m *Manager) rotateServicesWithoutOverlap() error { + return m.rotateServices((*Manager).resetAndApplyTLSSecret) +} + +func (m *Manager) rotateServicesWithOverlap() error { + return m.rotateServices((*Manager).appendAndApplyTLSSecret) +} + +func (m *Manager) rotateServices(applyFn func(*Manager, types.NamespacedName, *triple.KeyPair) error) error { m.log.Info("Rotating Services cert/key") webhook, err := m.readyWebhookConfiguration() @@ -186,7 +198,7 @@ func (m *Manager) rotateServices() error { if err != nil { return errors.Wrapf(err, "failed creating server key/cert for service %+v", service) } - err = m.applyTLSSecret(service, keyPair) + err = applyFn(m, service, keyPair) if err != nil { return errors.Wrapf(err, "failed applying TLS secret %s", service) } @@ -231,19 +243,16 @@ func (m *Manager) nextRotationDeadlineForServices() time.Time { } } - nextDeadline := m.nextRotationDeadlineForCert(nextToExpireServiceCert) + nextDeadline := m.nextRotationDeadlineForCert(nextToExpireServiceCert, m.serviceOverlapDuration) // Store last calculated deadline to use it at Reconcile m.lastRotateDeadlineForServices = &nextDeadline return nextDeadline - - return m.now() } -// nextRotationDeadline returns a value for the threshold at which the -// current certificate should be rotated, 80%+/-10% of the expiration of the -// certificate or force rotation in case the certificate chain is faulty -func (m *Manager) nextRotationDeadline() time.Time { +// nextRotationDeadlineForCA verifty that TLS chain is ok, check rotation from +// last certificate at CABundle using nextRotationDeadlineForCert +func (m *Manager) nextRotationDeadlineForCA() time.Time { err := m.verifyTLS() if err != nil { // Sprintf is used to prevent stack trace to be printed @@ -258,7 +267,7 @@ func (m *Manager) nextRotationDeadline() time.Time { m.log.Info("Failed reading last CA cert from CABundle, forcing rotation", "err", err) return m.now() } - nextDeadline := m.nextRotationDeadlineForCert(caCert) + nextDeadline := m.nextRotationDeadlineForCert(caCert, m.caOverlapDuration) // Store last calculated deadline to use it at Reconcile m.lastRotateDeadline = &nextDeadline @@ -266,12 +275,13 @@ func (m *Manager) nextRotationDeadline() time.Time { } // nextRotationDeadlineForCert returns a value for the threshold at which the -// current certificate should be rotated, 80%+/-10% of the expiration of the -// certificate -func (m *Manager) nextRotationDeadlineForCert(certificate *x509.Certificate) time.Time { +// current certificate should be rotated, the expiration of the +// certificate - overlap +func (m *Manager) nextRotationDeadlineForCert(certificate *x509.Certificate, overlap time.Duration) time.Time { notAfter := certificate.NotAfter totalDuration := float64(notAfter.Sub(certificate.NotBefore)) - deadline := certificate.NotBefore.Add(jitteryDuration(totalDuration)) + deadlineDuration := totalDuration - float64(overlap) + deadline := certificate.NotBefore.Add(time.Duration(deadlineDuration)) m.log.Info(fmt.Sprintf("Certificate expiration is %v, totalDuration is %v, rotation deadline is %v", notAfter, totalDuration, deadline)) return deadline @@ -285,7 +295,7 @@ func (m *Manager) elapsedToRotateCAFromLastDeadline() time.Duration { if m.lastRotateDeadline != nil { deadline = *m.lastRotateDeadline } else { - deadline = m.nextRotationDeadline() + deadline = m.nextRotationDeadlineForCA() } now := m.now() elapsedToRotate := deadline.Sub(now) @@ -345,15 +355,3 @@ func (m *Manager) verifyTLS() error { return nil } - -// jitteryDuration uses some jitter to set the rotation threshold so each node -// will rotate at approximately 70-90% of the total lifetime of the -// certificate. With jitter, if a number of nodes are added to a cluster at -// approximately the same time (such as cluster creation time), they won't all -// try to rotate certificates at the same time for the rest of the life of the -// cluster. -// -// This function is represented as a variable to allow replacement during testing. -var jitteryDuration = func(totalDuration float64) time.Duration { - return wait.Jitter(time.Duration(totalDuration), 0.2) - time.Duration(totalDuration*0.3) -} diff --git a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/options.go b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/options.go index 8f84f0281..f7c245b92 100644 --- a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/options.go +++ b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/options.go @@ -36,6 +36,10 @@ type Options struct { // the the webhook configuration is referencing different services all // of them will share the same duration CertRotateInterval time.Duration + + // CertOverlapInterval the duration of service certificates at bundle if + // not set it will default to CertRotateInterval + CertOverlapInterval time.Duration } func (o *Options) validate() error { @@ -54,6 +58,10 @@ func (o *Options) validate() error { return fmt.Errorf("failed validating certificate options, 'CertRotateInterval' has to be <= 'CARotateInterval'") } + if o.CertOverlapInterval > o.CertRotateInterval { + return fmt.Errorf("failed validating certificate options, 'CertOverlapInterval' has to be <= 'CertRotateInterval'") + } + if o.WebhookType != MutatingWebhook && o.WebhookType != ValidatingWebhook { return fmt.Errorf("failed validating certificate options, 'WebhookType' has to be %s or %s", MutatingWebhook, ValidatingWebhook) } @@ -79,6 +87,10 @@ func (o Options) withDefaults() Options { if o.CertRotateInterval == 0 { withDefaultsOptions.CertRotateInterval = withDefaultsOptions.CARotateInterval } + + if o.CertOverlapInterval == 0 { + withDefaultsOptions.CertOverlapInterval = withDefaultsOptions.CertRotateInterval + } return withDefaultsOptions } diff --git a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/secret.go b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/secret.go index 3a9a3b841..e8fb961dd 100644 --- a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/secret.go +++ b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/secret.go @@ -3,6 +3,7 @@ package certificate import ( "context" "crypto/rsa" + "crypto/x509" "reflect" "github.com/pkg/errors" @@ -22,7 +23,7 @@ const ( CAPrivateKeyKey = "ca.key" ) -func populateCASecret(secret corev1.Secret, keyPair *triple.KeyPair) *corev1.Secret { +func populateCASecret(secret corev1.Secret, keyPair *triple.KeyPair) (*corev1.Secret, error) { if secret.Annotations == nil { secret.Annotations = map[string]string{} } @@ -31,23 +32,65 @@ func populateCASecret(secret corev1.Secret, keyPair *triple.KeyPair) *corev1.Sec CACertKey: triple.EncodeCertPEM(keyPair.Cert), CAPrivateKeyKey: triple.EncodePrivateKeyPEM(keyPair.Key), } - return &secret + return &secret, nil } -func populateTLSSecret(secret corev1.Secret, keyPair *triple.KeyPair) *corev1.Secret { +func addTLSCertificate(data map[string][]byte, cert *x509.Certificate) error { + + certsPEM, hasCerts := data[corev1.TLSCertKey] + if hasCerts { + certsPEMBytes, err := triple.AddCertToPEM(cert, []byte(certsPEM)) + if err != nil { + return err + } + certsPEM = certsPEMBytes + } else { + certsPEM = triple.EncodeCertPEM(cert) + } + data[corev1.TLSCertKey] = certsPEM + return nil +} + +func setAnnotation(secret *corev1.Secret) { if secret.Annotations == nil { secret.Annotations = map[string]string{} } secret.Annotations[secretManagedAnnotatoinKey] = "" +} + +func resetTLSSecret(secret corev1.Secret, keyPair *triple.KeyPair) (*corev1.Secret, error) { + setAnnotation(&secret) + secret.Data = map[string][]byte{ - corev1.TLSCertKey: triple.EncodeCertPEM(keyPair.Cert), corev1.TLSPrivateKeyKey: triple.EncodePrivateKeyPEM(keyPair.Key), + corev1.TLSCertKey: triple.EncodeCertPEM(keyPair.Cert), } - return &secret + return &secret, nil } -func (m *Manager) applyTLSSecret(secret types.NamespacedName, keyPair *triple.KeyPair) error { - return m.applySecret(secret, corev1.SecretTypeTLS, keyPair, populateTLSSecret) +func appendTLSSecret(secret corev1.Secret, keyPair *triple.KeyPair) (*corev1.Secret, error) { + setAnnotation(&secret) + + if secret.Data == nil { + secret.Data = map[string][]byte{} + } + + err := addTLSCertificate(secret.Data, keyPair.Cert) + if err != nil { + return nil, err + } + + secret.Data[corev1.TLSPrivateKeyKey] = triple.EncodePrivateKeyPEM(keyPair.Key) + + return &secret, nil +} + +func (m *Manager) resetAndApplyTLSSecret(secret types.NamespacedName, keyPair *triple.KeyPair) error { + return m.applySecret(secret, corev1.SecretTypeTLS, keyPair, resetTLSSecret) +} + +func (m *Manager) appendAndApplyTLSSecret(secret types.NamespacedName, keyPair *triple.KeyPair) error { + return m.applySecret(secret, corev1.SecretTypeTLS, keyPair, appendTLSSecret) } func (m *Manager) applyCASecret(keyPair *triple.KeyPair) error { @@ -55,7 +98,7 @@ func (m *Manager) applyCASecret(keyPair *triple.KeyPair) error { } func (m *Manager) applySecret(secretKey types.NamespacedName, secretType corev1.SecretType, keyPair *triple.KeyPair, - populateSecretFn func(corev1.Secret, *triple.KeyPair) *corev1.Secret) error { + populateSecretFn func(corev1.Secret, *triple.KeyPair) (*corev1.Secret, error)) error { secret := corev1.Secret{} return retry.RetryOnConflict(retry.DefaultRetry, func() error { @@ -70,7 +113,11 @@ func (m *Manager) applySecret(secretKey types.NamespacedName, secretType corev1. }, Type: secretType, } - err = m.client.Create(context.TODO(), populateSecretFn(newSecret, keyPair)) + populatedSecret, err := populateSecretFn(newSecret, keyPair) + if err != nil { + return errors.Wrap(err, "failed populating secret") + } + err = m.client.Create(context.TODO(), populatedSecret) if err != nil { return errors.Wrap(err, "failed creating secret") } @@ -79,7 +126,11 @@ func (m *Manager) applySecret(secretKey types.NamespacedName, secretType corev1. return err } } - err = m.client.Update(context.TODO(), populateSecretFn(secret, keyPair)) + populatedSecret, err := populateSecretFn(secret, keyPair) + if err != nil { + return errors.Wrap(err, "failed populating secret") + } + err = m.client.Update(context.TODO(), populatedSecret) if err != nil { return errors.Wrap(err, "failed updating secret") } @@ -115,7 +166,7 @@ func (m *Manager) verifyTLSSecret(secretKey types.NamespacedName, caKeyPair *tri return errors.New("CA bundle has no certificates") } - lastCertFromCABundle := certsFromCABundle[len(certsFromCABundle)-1] + lastCertFromCABundle := getLastCert(certsFromCABundle) if !reflect.DeepEqual(*lastCertFromCABundle, *caKeyPair.Cert) { return errors.New("CA bundle and CA secret certificate are different") @@ -184,10 +235,41 @@ func (m *Manager) getTLSKeyPair(secretKey types.NamespacedName) (*triple.KeyPair if err != nil { return nil, errors.Wrapf(err, "failed parsing TLS private key PEM at secret %s", secretKey) } - return &triple.KeyPair{Key: privateKey.(*rsa.PrivateKey), Cert: certs[0]}, nil + + lastAppendedCert := getLastCert(certs) + + return &triple.KeyPair{Key: privateKey.(*rsa.PrivateKey), Cert: lastAppendedCert}, nil +} + +func (m *Manager) getTLSCerts(secretKey types.NamespacedName) ([]*x509.Certificate, error) { + secret := corev1.Secret{} + err := m.get(secretKey, &secret) + if err != nil { + return nil, errors.Wrapf(err, "failed reading ca secret %s", secretKey) + } + + certPEM, found := secret.Data[corev1.TLSCertKey] + if !found { + return nil, errors.Wrapf(err, "TLS cert not found at secret %s", secretKey) + } + + certs, err := triple.ParseCertsPEM(certPEM) + if err != nil { + return nil, errors.Wrapf(err, "failed parsing TLS cert PEM at secret %s", secretKey) + } + return certs, nil } //FIXME: Is this default/webhookname good key for ca secret func (m *Manager) caSecretKey() types.NamespacedName { return types.NamespacedName{Namespace: m.namespace, Name: m.webhookName + "-ca"} } + +// Certs are appended to implement overlap so we take the last one +// it will match with the key +func getLastCert(certs []*x509.Certificate) *x509.Certificate { + if len(certs) == 0 { + return nil + } + return certs[len(certs)-1] +} diff --git a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/triple/pem.go b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/triple/pem.go index 9916819ce..f34666f12 100644 --- a/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/triple/pem.go +++ b/vendor/github.com/qinqon/kube-admission-webhook/pkg/certificate/triple/pem.go @@ -188,6 +188,19 @@ func ParseCertsPEM(pemCerts []byte) ([]*x509.Certificate, error) { return certs, nil } +func AddCertToPEM(cert *x509.Certificate, pemCerts []byte) ([]byte, error) { + certs := []*x509.Certificate{} + if len(pemCerts) > 0 { + var err error + certs, err = ParseCertsPEM(pemCerts) + if err != nil { + return nil, fmt.Errorf("failed parsing current certs PEM: %w", err) + } + } + certs = append(certs, cert) + return EncodeCertsPEM(certs), nil +} + // parseRSAPublicKey parses a single RSA public key from the provided data func parseRSAPublicKey(data []byte) (*rsa.PublicKey, error) { var err error diff --git a/vendor/golang.org/x/net/html/const.go b/vendor/golang.org/x/net/html/const.go index 73804d347..ff7acf2d5 100644 --- a/vendor/golang.org/x/net/html/const.go +++ b/vendor/golang.org/x/net/html/const.go @@ -52,7 +52,7 @@ var isSpecialElementMap = map[string]bool{ "iframe": true, "img": true, "input": true, - "keygen": true, + "keygen": true, // "keygen" has been removed from the spec, but are kept here for backwards compatibility. "li": true, "link": true, "listing": true, diff --git a/vendor/golang.org/x/net/html/foreign.go b/vendor/golang.org/x/net/html/foreign.go index 74774c458..9da9e9dc4 100644 --- a/vendor/golang.org/x/net/html/foreign.go +++ b/vendor/golang.org/x/net/html/foreign.go @@ -161,65 +161,62 @@ var mathMLAttributeAdjustments = map[string]string{ } var svgAttributeAdjustments = map[string]string{ - "attributename": "attributeName", - "attributetype": "attributeType", - "basefrequency": "baseFrequency", - "baseprofile": "baseProfile", - "calcmode": "calcMode", - "clippathunits": "clipPathUnits", - "contentscripttype": "contentScriptType", - "contentstyletype": "contentStyleType", - "diffuseconstant": "diffuseConstant", - "edgemode": "edgeMode", - "externalresourcesrequired": "externalResourcesRequired", - "filterunits": "filterUnits", - "glyphref": "glyphRef", - "gradienttransform": "gradientTransform", - "gradientunits": "gradientUnits", - "kernelmatrix": "kernelMatrix", - "kernelunitlength": "kernelUnitLength", - "keypoints": "keyPoints", - "keysplines": "keySplines", - "keytimes": "keyTimes", - "lengthadjust": "lengthAdjust", - "limitingconeangle": "limitingConeAngle", - "markerheight": "markerHeight", - "markerunits": "markerUnits", - "markerwidth": "markerWidth", - "maskcontentunits": "maskContentUnits", - "maskunits": "maskUnits", - "numoctaves": "numOctaves", - "pathlength": "pathLength", - "patterncontentunits": "patternContentUnits", - "patterntransform": "patternTransform", - "patternunits": "patternUnits", - "pointsatx": "pointsAtX", - "pointsaty": "pointsAtY", - "pointsatz": "pointsAtZ", - "preservealpha": "preserveAlpha", - "preserveaspectratio": "preserveAspectRatio", - "primitiveunits": "primitiveUnits", - "refx": "refX", - "refy": "refY", - "repeatcount": "repeatCount", - "repeatdur": "repeatDur", - "requiredextensions": "requiredExtensions", - "requiredfeatures": "requiredFeatures", - "specularconstant": "specularConstant", - "specularexponent": "specularExponent", - "spreadmethod": "spreadMethod", - "startoffset": "startOffset", - "stddeviation": "stdDeviation", - "stitchtiles": "stitchTiles", - "surfacescale": "surfaceScale", - "systemlanguage": "systemLanguage", - "tablevalues": "tableValues", - "targetx": "targetX", - "targety": "targetY", - "textlength": "textLength", - "viewbox": "viewBox", - "viewtarget": "viewTarget", - "xchannelselector": "xChannelSelector", - "ychannelselector": "yChannelSelector", - "zoomandpan": "zoomAndPan", + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan", } diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go index 2cd12fc81..f91466f7c 100644 --- a/vendor/golang.org/x/net/html/parse.go +++ b/vendor/golang.org/x/net/html/parse.go @@ -728,7 +728,13 @@ func inHeadNoscriptIM(p *parser) bool { return inBodyIM(p) case a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Style: return inHeadIM(p) - case a.Head, a.Noscript: + case a.Head: + // Ignore the token. + return true + case a.Noscript: + // Don't let the tokenizer go into raw text mode even when a