From 41435e88fd605f42cebc9ec62e9f6247242a5c7e Mon Sep 17 00:00:00 2001 From: Amit Kumar Das Date: Wed, 9 Oct 2019 12:55:26 +0530 Subject: [PATCH] [usecase, gctl]: showcase install/un-install of CRD (#28) This commit showcases how GenericController can be used to install and uninstall a CRD when a particular namespace gets created and deleted correspondingly. This commit can be understood in two ways: 1/ Files in test/integration/generic/ shows how golang based integration code can be written to verify this use-case. 2/ Files in examples/gctl/install-uninstall-crd/ shows how metac controller & jsonnet files are used to verify this use-case. NOTES: 1/ There are some changes to vendoring as well. Latest k8s.io dependencies are set. 2/ Integration test case has been set to run only if test is not run in short mode. Signed-off-by: AmitKumarDas --- Makefile | 10 +- TODO | 46 +-- controller/common/manage_attachments.go | 19 +- examples/gctl/install-uninstall-crd/README.md | 59 ++++ .../hooks/finalize-crd.jsonnet | 7 + .../hooks/sync-crd.jsonnet | 54 ++++ .../install-uninstall-crd/my-namespace.yaml | 5 + .../gctl/install-uninstall-crd/operator.yaml | 71 +++++ examples/gctl/install-uninstall-crd/test.sh | 68 ++++ go.mod | 35 +- go.sum | 103 ++++++ manifests/metacontroller.yaml | 2 - test/integration/framework/fixture.go | 4 +- test/integration/framework/helper.go | 9 +- ...nstall_test.go => clean_uninstall_test.go} | 6 +- .../generic/crd_apply_delete_test.go | 300 ++++++++++++++++++ test/integration/generic/generic_test.go | 12 - test/integration/generic/suite_test.go | 34 ++ 18 files changed, 783 insertions(+), 61 deletions(-) create mode 100644 examples/gctl/install-uninstall-crd/README.md create mode 100644 examples/gctl/install-uninstall-crd/hooks/finalize-crd.jsonnet create mode 100644 examples/gctl/install-uninstall-crd/hooks/sync-crd.jsonnet create mode 100644 examples/gctl/install-uninstall-crd/my-namespace.yaml create mode 100644 examples/gctl/install-uninstall-crd/operator.yaml create mode 100755 examples/gctl/install-uninstall-crd/test.sh rename test/integration/generic/{ns_crd_uninstall_test.go => clean_uninstall_test.go} (98%) create mode 100644 test/integration/generic/crd_apply_delete_test.go create mode 100644 test/integration/generic/suite_test.go diff --git a/Makefile b/Makefile index 08ad059..2a3b12a 100644 --- a/Makefile +++ b/Makefile @@ -63,4 +63,12 @@ integration-dependencies: # This can be run on one's laptop or Travis like CI environments. .PHONY: integration-test integration-test: generated_files integration-dependencies - @PATH="$(PWD)/hack/bin:$(PATH)" go test ./test/integration/... -v -timeout 5m -args --logtostderr -v=1 \ No newline at end of file + @PATH="$(PWD)/hack/bin:$(PATH)" \ + go test ./test/integration/... -v -short -timeout 5m \ + -args --logtostderr -v=1 + +.PHONY: integration-test-gctl +integration-test-gctl: generated_files integration-dependencies + @PATH="$(PWD)/hack/bin:$(PATH)" \ + go test ./test/integration/generic/... -v -timeout 5m \ + -args --logtostderr -v=1 \ No newline at end of file diff --git a/TODO b/TODO index 52e53f0..beb44fa 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,7 @@ ### TODO: -- test metac with changes to rbac - -- gctl add integration tests: +- Test metac with changes to rbac +- Make all examples to work & then make it better +- Add integration tests w.r.t GenericController: - check if finalizer works - check if attachments not created by gctl are not updated - check if attachments not created by gctl are not deleted @@ -19,44 +19,46 @@ - operator - WatchIsOwner, WatchIsCreator, WatchIsUpdater - operator - WatchInKey, WatchInValue, ValueContainsWatch, KeyContainsWatch -- gctl - read & review +### Blogs: +- Integration Tests + - go based integration tests vs. bash based vs GCtl based + - Blog talks only about GCtl tests & give links to how Go & Bash are done + +### Learn: +- read & review & compare them against GenericController - https://github.com/GoogleCloudPlatform/metacontroller/issues/98 - https://github.com/GoogleCloudPlatform/metacontroller/pull/143 - https://github.com/GoogleCloudPlatform/metacontroller/pull/168 +### Few targeted usecases: + - ConformanceTest + - CStorConfigController + - DDP + - Install + - UnInstall + - Upgrade -- all controller enhancements +### Future actions: +- All controller enhancements - https://github.com/GoogleCloudPlatform/metacontroller/issues/154 - make Metac run based on either of following: - CustomResource, or # current mode - Config # default mode - make cctl, dctl & gctl work from config files vs. current way that depends on CRDs - -- explore the one binary sidecars +- Explore the one binary sidecars - jsonnetd service + hooks as a docker image - -- gctl integration test - - code refactoring - one .go file per test - - proper logs, informative logs, proper log levels - Use latest stable Kubernetes version & etcd for integration testing -- make all examples to work & then make it better - restructure examples to enable community - code to use klog - test/unittest - find bugs & fix - -- targeted usecases - - ConformanceTest - - CStorConfigController - - DDP - - Install - - UnInstall - - Upgrade - -### Future Actions: - Make metacontroller watch resources from specific namespace if required - Should Metac support UDS? - https://eli.thegreenplace.net/2019/unix-domain-sockets-in-go/ +- >>enisoc 2:08 AM + if the new client-go dynamic informer does everything metacontroller needs + (e.g. start/stop dynamically without process restart), it would be great to + rebase metacontroller on client-go's dynamic package ### Meeting Notes & Agenda - https://docs.google.com/document/d/1HV_Fr0wIW9tr5OZwK_6oGux_OhcGtxxWWV6dCYJR9Cw/ diff --git a/controller/common/manage_attachments.go b/controller/common/manage_attachments.go index 5dff57d..bb74890 100644 --- a/controller/common/manage_attachments.go +++ b/controller/common/manage_attachments.go @@ -206,9 +206,12 @@ func (m AttachmentManager) String() string { return m.AttachmentExecuteBase.String() } -// preApply prepares the manager before invoking the Apply -// This method sets various default options if applicable -func (m *AttachmentManager) preApply() { +// setDefaults prepares the attachment manager before invoking the +// Apply +// +// NOTE: +// This method sets various **default** options if applicable +func (m *AttachmentManager) setDefaults() { if m.DeleteFn == nil { m.errs = appendErrIfNotNil( m.errs, anyAttachmentsDefaultDeleter()(m), @@ -220,16 +223,18 @@ func (m *AttachmentManager) preApply() { ) } if m.IsWatchOwner == nil { - // defaults to set this watch as not the owner - // of the attachments - m.IsWatchOwner = kubernetes.BoolPtr(false) + // defaults to set this watch as the owner of the + // attachments, since this tunable is used only during + // creation of these attachment(s) while observing the + // watch resource + m.IsWatchOwner = kubernetes.BoolPtr(true) } } // Apply executes create, delete or update operations against // the child resources set against this manager instance func (m *AttachmentManager) Apply() error { - m.preApply() + m.setDefaults() if len(m.errs) != 0 { return utilerrors.NewAggregate(m.errs) } diff --git a/examples/gctl/install-uninstall-crd/README.md b/examples/gctl/install-uninstall-crd/README.md new file mode 100644 index 0000000..f516658 --- /dev/null +++ b/examples/gctl/install-uninstall-crd/README.md @@ -0,0 +1,59 @@ +## Install-Uninstall-CRD + +This is an example of GenericController that adds a CRD for a given Namespace. +This also removes the CRD when the given Namespace is deleted. + +### Prerequisites + +* Kubernetes 1.8+ is recommended for its improved CRD support, especially garbage collection. +* Install Metac using yamls from manifests folder + +```sh +# cd to metac's root folder + +kubectl apply -f ./manifests/metacontroller-namespace.yaml +kubectl apply -f ./manifests/metacontroller-rbac.yaml +kubectl apply -f ./manifests/metacontroller.yaml + +# verify if metac was installed properly +kubectl get crd +kubectl get sts -n metac +``` + +### Deploy the Controllers + +```sh +# cd to examples/gctl/install-uninstall-crd/ + +# any change in any of the hooks should be accompanied +# by deleting 1/ configmap & 2/ operator & 3/ re-applying both +kubectl create configmap install-uninstall-crd -n metac --from-file=hooks +kubectl apply -f operator.yaml + +# verify the deploy, svc & configmap of this example +kubectl get gctl +kubectl get cm -n metac +kubectl get deploy -n metac +kubectl get svc -n metac +``` + +### Create the Namespace + +```sh +kubectl apply -f my-namespace.yaml +``` + +Watch for the CRD to get created: + +```sh +kubectl get crds --watch + +kubectl get crd storages.dao.amitd.io +``` + +Check that the CRD get cleaned up when this Namespace is deleted: + +```sh +kubectl delete -f my-namespace.yaml +kubectl get crds --watch +``` \ No newline at end of file diff --git a/examples/gctl/install-uninstall-crd/hooks/finalize-crd.jsonnet b/examples/gctl/install-uninstall-crd/hooks/finalize-crd.jsonnet new file mode 100644 index 0000000..123755b --- /dev/null +++ b/examples/gctl/install-uninstall-crd/hooks/finalize-crd.jsonnet @@ -0,0 +1,7 @@ +function(request) { + // Delete the CRD since namespace is observed + // to being deleted + attachments: [], + // Mark as finalized once we observe this CRD are gone. + finalized: std.length(request.attachments['CustomResourceDefinition.apiextensions.k8s.io/v1beta1']) == 0 +} diff --git a/examples/gctl/install-uninstall-crd/hooks/sync-crd.jsonnet b/examples/gctl/install-uninstall-crd/hooks/sync-crd.jsonnet new file mode 100644 index 0000000..69492b6 --- /dev/null +++ b/examples/gctl/install-uninstall-crd/hooks/sync-crd.jsonnet @@ -0,0 +1,54 @@ +function(request) { + // Create a CRD for the namespace specified in GenericController + attachments: [ + { + apiVersion: "apiextensions.k8s.io/v1beta1", + kind: "CustomResourceDefinition", + metadata: { + // name must match the spec fields below, and be in the form: + // . + name: "storages.dao.amitd.io", + }, + spec: { + // group name to use for REST API: /apis// + group: "dao.amitd.io", + // version name to use for REST API: /apis// + version: "v1alpha1", + // either Namespaced or Cluster + scope: "Namespaced", + names:{ + // plural name to be used in the URL: + // i.e. /apis/// + plural: "storages", + // # singular name to be used as an alias on the CLI and for display + singular: "storage", + // kind is normally the CamelCased singular type. + // Your resource manifests use this. + kind: "Storage", + # shortNames allow shorter string to match your resource on the CLI + shortNames: ["stor"], + }, + additionalPrinterColumns: [ + { + JSONPath: ".spec.capacity", + name: "Capacity", + description: "Capacity of the storage", + type: "string", + }, + { + JSONPath: ".spec.nodeName", + name: "NodeName", + description: "Node where the storage gets attached", + type: "string", + }, + { + JSONPath: ".status.phase", + name: "Status", + description: "Identifies the current status of the storage", + type: "string", + }, + ], + } + } + ] +} diff --git a/examples/gctl/install-uninstall-crd/my-namespace.yaml b/examples/gctl/install-uninstall-crd/my-namespace.yaml new file mode 100644 index 0000000..11cab0c --- /dev/null +++ b/examples/gctl/install-uninstall-crd/my-namespace.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: amitd +--- \ No newline at end of file diff --git a/examples/gctl/install-uninstall-crd/operator.yaml b/examples/gctl/install-uninstall-crd/operator.yaml new file mode 100644 index 0000000..b9de19e --- /dev/null +++ b/examples/gctl/install-uninstall-crd/operator.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: metac.openebs.io/v1alpha1 +kind: GenericController +metadata: + name: install-un-crd +spec: + watch: + apiVersion: v1 + resource: namespaces + nameSelector: + # we are interested in amitd namespace only + - amitd + attachments: + - apiVersion: apiextensions.k8s.io/v1beta1 + resource: customresourcedefinitions + nameSelector: + # we are interested in storages CRD only + - storages.dao.amitd.io + hooks: + sync: + webhook: + url: http://jsonnetd.metac/sync-crd + finalize: + webhook: + url: http://jsonnetd.metac/finalize-crd +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: jsonnetd + namespace: metac +spec: + replicas: 1 + selector: + matchLabels: + app: jsonnetd + template: + metadata: + labels: + app: jsonnetd + spec: + containers: + - name: hooks + # this deployment is all about exposing jsonnet as a webhook + # that understands metac request & response payload + image: metacontroller/jsonnetd:0.1 + imagePullPolicy: Always + workingDir: /hooks + volumeMounts: + - name: hooks + mountPath: /hooks + volumes: + - name: hooks + configMap: + # this configmap provides the jsonnet files that + # get executed as webhooks + name: install-uninstall-crd +--- +apiVersion: v1 +kind: Service +metadata: + # this name is used to build the webhook url + name: jsonnetd + # this namespace is used to build the webhook url + namespace: metac +spec: + selector: + app: jsonnetd + ports: + - port: 80 + targetPort: 8080 diff --git a/examples/gctl/install-uninstall-crd/test.sh b/examples/gctl/install-uninstall-crd/test.sh new file mode 100755 index 0000000..5441ac2 --- /dev/null +++ b/examples/gctl/install-uninstall-crd/test.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +cleanup() { + set +e + + echo "" + + echo "--------------------------" + echo "++ Clean up started" + echo "--------------------------" + + kubectl patch namespace amitd --type=merge -p '{"metadata":{"finalizers":[]}}' || true + kubectl delete -f my-namespace.yaml || true + kubectl delete -f operator.yaml || true + kubectl delete configmap install-uninstall-crd -n metac || true + kubectl delete crd storages.dao.amitd.io || true + + echo "--------------------------" + echo "++ Clean up completed" + echo "--------------------------" +} +trap cleanup EXIT + +# Uncomment this if you want to run this script in debug mode +#set -ex + +# my crd name +my_crd="storages.dao.amitd.io" + +echo -e "\n++ Installing operator" +kubectl create configmap install-uninstall-crd -n metac --from-file=hooks +kubectl apply -f operator.yaml +echo -e "\n++ Installed operator successfully" + + +echo -e "\n++ Applying namespace that will get watched by metac - I" +kubectl apply -f my-namespace.yaml +echo -e "\n++ Applied namespace successfully" + +echo -e "\n++ Waiting for CRD $my_crd creation..." +until kubectl get crd $my_crd; do sleep 1; done +echo -e "\n++ CRD $my_crd created successfully" + +echo -e "\n++ Deleting namespace that is being watched by metac - II" +kubectl delete -f my-namespace.yaml +echo -e "\n++ Deleted namespace successfully" + +echo -e "\n++ Waiting for CRD $my_crd deletion..." +until [[ "$(kubectl get crd $my_crd 2>&1)" == *NotFound* ]]; do sleep 1; done +echo -e "\n++ Deleted CRD $my_crd successfully" + +echo -e "\n++ Applying namespace that will get watched by metac - III" +kubectl apply -f my-namespace.yaml +echo -e "\n++ Applied namespace successfully" + +echo -e "\n++ Waiting for CRD $my_crd creation..." +until kubectl get crd $my_crd; do sleep 1; done +echo -e "\n++ CRD $my_crd created successfully" + +echo -e "\n++ Deleting namespace that is being watched by metac - IV" +kubectl delete -f my-namespace.yaml +echo -e "\n++ Deleted namespace successfully" + +echo -e "\n++ Waiting for CRD $my_crd deletion..." +until [[ "$(kubectl get crd $my_crd 2>&1)" == *NotFound* ]]; do sleep 1; done +echo -e "\n++ CRD $my_crd deleted successfully" + +echo -e "\n++ Test install-uninstall-crd completed successfully..." \ No newline at end of file diff --git a/go.mod b/go.mod index 8f6f7e4..b476be5 100644 --- a/go.mod +++ b/go.mod @@ -4,18 +4,31 @@ go 1.12 require ( contrib.go.opencensus.io/exporter/prometheus v0.1.0 - github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4 + github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/google/go-cmp v0.3.0 - github.com/google/go-jsonnet v0.13.0 - github.com/imdario/mergo v0.3.7 // indirect + github.com/google/go-jsonnet v0.14.0 github.com/pkg/errors v0.8.1 - go.opencensus.io v0.22.0 - golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect - k8s.io/api v0.0.0-20190813220812-4c9d9526570f - k8s.io/apiextensions-apiserver v0.0.0-20190814062247-6b65a6b808ce - k8s.io/apimachinery v0.0.0-20190813235223-d2c4b5819cd0 - k8s.io/client-go v0.0.0-20190813221022-7eecfc25a0aa - k8s.io/code-generator v0.0.0-20190814020510-48723802c45e - k8s.io/klog v0.4.0 + go.opencensus.io v0.21.0 + k8s.io/api v0.0.0-20191005115622-2e41325d9e4b + k8s.io/apiextensions-apiserver v0.0.0-20191008120836-c5dfed5b5134 + k8s.io/apimachinery v0.0.0-20191006235458-f9f2f3f8ab02 + k8s.io/client-go v0.0.0-20191008115822-1210218b4a26 + k8s.io/code-generator v0.0.0-20191003035328-700b1226c0bd + k8s.io/klog v1.0.0 + k8s.io/klog/v2 v2.0.0-20190919174302-ab80cd2723c2 // indirect +) + +replace ( + golang.org/x/crypto => golang.org/x/crypto v0.0.0-20181025213731-e84da0312774 + golang.org/x/lint => golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1 + golang.org/x/oauth2 => golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a + golang.org/x/sync => golang.org/x/sync v0.0.0-20181108010431-42b317875d0f + golang.org/x/sys => golang.org/x/sys v0.0.0-20190209173611-3b5209105503 + golang.org/x/text => golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db + golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d + k8s.io/api => k8s.io/api v0.0.0-20191005115622-2e41325d9e4b + k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191005115455-e71eb83a557c + k8s.io/client-go => k8s.io/client-go v0.0.0-20191005115821-b1fd78950135 + k8s.io/code-generator => k8s.io/code-generator v0.0.0-20191003035328-700b1226c0bd ) diff --git a/go.sum b/go.sum index d1cfe0a..64ceadc 100644 --- a/go.sum +++ b/go.sum @@ -1,32 +1,49 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= contrib.go.opencensus.io/exporter/prometheus v0.1.0 h1:SByaIoWwNgMdPSgl5sMqM2KDE5H/ukPWBRo314xiDvg= contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v0.0.0-20180117170138-065b426bd416/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -34,22 +51,28 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 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/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4 h1:bRzFpEzvausOAt4va+I/22BZ1vXDtERngp0BNYDKej0= github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -61,10 +84,12 @@ github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -75,6 +100,7 @@ github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= @@ -82,9 +108,12 @@ github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+Z github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= @@ -92,21 +121,28 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-jsonnet v0.13.0 h1:Ul0FtJiQl705JIyGKaBZug/W2LBY5p0xwY08Q69eOAg= github.com/google/go-jsonnet v0.13.0/go.mod h1:gNwctc8xrpXNs749bjRLO58rjIBVrWz+pgsRoOCh5Vs= +github.com/google/go-jsonnet v0.14.0 h1:as/sAfmjOHqY/OMBR4mv9I8ZY0/jNuqN3u44AicwxPs= +github.com/google/go-jsonnet v0.14.0/go.mod h1:zPGC9lj/TbjkBtUACIvYR/ILHrFqKRhxeEA+bLyeMnY= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -115,6 +151,7 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20170330212424-2500245aa611/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= @@ -122,6 +159,7 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -131,9 +169,12 @@ github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBv github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -144,6 +185,7 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -160,14 +202,17 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -178,24 +223,36 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v0.9.4 h1:Y8E/JaaPbmFSW2V81Ab/d8yZFYQQGbni1b1jPcG9Y6A= +github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= @@ -212,12 +269,15 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20181025213731-e84da0312774 h1:a4tQYYYuK9QdeO/+kEvNYyuR21S+7ve5EANok6hABhI= +golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -230,6 +290,7 @@ golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495 h1:I6A9Ag9FpEKOjcKrRNjQkPHaw golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= @@ -238,6 +299,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -247,6 +309,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= +golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -259,6 +323,7 @@ golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503 h1:5SvYFrOM3W8Mexn9/oA44Ji7vhXAZQ9hiP+1Q/DMrWg= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -271,8 +336,11 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 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/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wktg7Jn/a/fNmr33HSj8g= golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -284,13 +352,18 @@ golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SGrZkZixxWpwNCDiwJfh88= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= @@ -298,10 +371,14 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.13.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -316,34 +393,59 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.0.0-20190813220811-3b2b5017183f/go.mod h1:jQ/7CcVOYUjK7L7XC7+yxtZdjG6mm61Bmv9LU2K7M7c= k8s.io/api v0.0.0-20190813220812-4c9d9526570f h1:GJd1WsysDrD6nTMnNi43CygTi4c3akjY6wDGlxaL2KE= k8s.io/api v0.0.0-20190813220812-4c9d9526570f/go.mod h1:jQ/7CcVOYUjK7L7XC7+yxtZdjG6mm61Bmv9LU2K7M7c= +k8s.io/api v0.0.0-20191005115622-2e41325d9e4b h1:j1mSRwavnCC3Q5QpgH0ldhap5qeCnRuf7xl0l1VUzdM= +k8s.io/api v0.0.0-20191005115622-2e41325d9e4b/go.mod h1:V9fqJJO3eGaWUKb9e6wH3fx7JXl1IaSC1VhSLk7GJjA= k8s.io/apiextensions-apiserver v0.0.0-20190814062247-6b65a6b808ce h1:EcWDSloDN5yjFxsfjSF2P3ksCqhT26QNKLDtodcKepo= k8s.io/apiextensions-apiserver v0.0.0-20190814062247-6b65a6b808ce/go.mod h1:bsB0mF05H/7iViYcYSiV/DTrvfsJMa5qiN1sgRyjgJQ= +k8s.io/apiextensions-apiserver v0.0.0-20191008120836-c5dfed5b5134 h1:FJ0BnKeeLW01Tk3VXg9/soEBbao+3ZlY7sAj2AhTYp0= +k8s.io/apiextensions-apiserver v0.0.0-20191008120836-c5dfed5b5134/go.mod h1:SFuEQuJnbLzYNnPHQRcZSJWFapHGEoNQGK3GgiF2Or8= k8s.io/apimachinery v0.0.0-20190813220643-cbbcc3bf2cd4/go.mod h1:1Bb79pEWnDgUBI8vkD0vaOot2IDbQD8ONqOd66wgvlM= k8s.io/apimachinery v0.0.0-20190813235223-d2c4b5819cd0 h1:s6iZdpAvDnCFrFsHSJY9Psb3yiOQ24CEsXdPznMpKcQ= k8s.io/apimachinery v0.0.0-20190813235223-d2c4b5819cd0/go.mod h1:1Bb79pEWnDgUBI8vkD0vaOot2IDbQD8ONqOd66wgvlM= +k8s.io/apimachinery v0.0.0-20191005115455-e71eb83a557c h1:FtM+eSMYMvnIMrryXaITj7oerp5l1uetUQ0/BKsc/rg= +k8s.io/apimachinery v0.0.0-20191005115455-e71eb83a557c/go.mod h1:92mWDd8Ji2sw2157KIgino5wCxffA8KSvhW2oY4ypdw= k8s.io/apiserver v0.0.0-20190813221731-6af99f9aacc8/go.mod h1:T1O5UqABVmpyiR4eux5urLgy1UnTsaZTF3LjiVRQ/pc= +k8s.io/apiserver v0.0.0-20191008120233-c29386a6051d/go.mod h1:UIel6UVz+0dF5u8geO0TKs6jDgAWo5A+tWTDXhhaW4E= k8s.io/client-go v0.0.0-20190813221022-7eecfc25a0aa h1:vlscDL2G5FJS11EJ2TY8K2oxDkWwNBFUxe98QPItumE= k8s.io/client-go v0.0.0-20190813221022-7eecfc25a0aa/go.mod h1:PRnhdyP0dDkcB8IUDIQ60Y8JMgtT8ekSpfD8y4OWYB0= +k8s.io/client-go v0.0.0-20191005115821-b1fd78950135 h1:KRmmu0QoQRZxRuQVyzWs3fMyZ85ZJf7PpnnpH4FvuyU= +k8s.io/client-go v0.0.0-20191005115821-b1fd78950135/go.mod h1:y9Rvsae8RfW0HpclmE1lCx4wUxrLDRhXv9gh8SWYhvc= k8s.io/code-generator v0.0.0-20190814020510-48723802c45e h1:s6jgCe8dRgmOsh8wG0LtQdP79nmIOtkYCZMz3G4L0kA= k8s.io/code-generator v0.0.0-20190814020510-48723802c45e/go.mod h1:kAu54L+mgoFV8VavRlfxdyU07rqHBlS1OpjkbGrhp7Q= +k8s.io/code-generator v0.0.0-20191003035328-700b1226c0bd h1:5WjZ3cIbClYC5mJf+H/ODCo36y8rRqtZRxol4Ujln8c= +k8s.io/code-generator v0.0.0-20191003035328-700b1226c0bd/go.mod h1:HC9p4y3SBN+txSs8x57qmNPXFZ/CxdCHiDTNnocCSEw= k8s.io/component-base v0.0.0-20190813221503-3e62d79579c8/go.mod h1:ErYFdqU7q+0gcmr804no7o0xvnPZTM/kgDGK3kY1tSY= +k8s.io/component-base v0.0.0-20191008075918-86c6082c6a20/go.mod h1:igCPGAZkiLboFObJH55AZAiStdoMZRsCN14ENO28iGQ= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190813173942-955ffa8fcfc9 h1:/gJp8cw8+k4AxBNGZ5u5eRoCOzH3WVpY02K654HNiyU= k8s.io/gengo v0.0.0-20190813173942-955ffa8fcfc9/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190822140433-26a664648505 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKOxmGeKRbsXVmqYM= +k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ= k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0-20190919174302-ab80cd2723c2 h1:h4jO1p8EVaAIdQaTx9EqN2ggigodOgSrlisL9DMQ3+M= +k8s.io/klog/v2 v2.0.0-20190919174302-ab80cd2723c2/go.mod h1:q4PVo0BneA7GsUJvFqoEvOCVmYJP0c5Y4VxrAYpJrIk= k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058 h1:di3XCwddOR9cWBNpfgXaskhh6cgJuwcK54rvtwUaC10= k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= +k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ= +k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20190920012459-5008bf6f8cd6 h1:rfepARh/ECp66dk9TTmT//1PBkHffjnxhdOrgH4m+eA= +k8s.io/utils v0.0.0-20190920012459-5008bf6f8cd6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= metacontroller.app v0.4.0 h1:MyD/Nu2QteqW1m9Xmu9XQdwjea2A6+lauDG9JOzd/1E= metacontroller.app v0.4.0/go.mod h1:xdD1o04SRpwqnl0+9u0TDO4BIul7U0w6EZUYg85pUwU= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= @@ -353,5 +455,6 @@ modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190724202554-0c1d754dd648/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= +sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/manifests/metacontroller.yaml b/manifests/metacontroller.yaml index 6661c6d..5b7b682 100644 --- a/manifests/metacontroller.yaml +++ b/manifests/metacontroller.yaml @@ -83,6 +83,4 @@ spec: - --logtostderr - -v=1 - --discovery-interval=20s - imagePullSecrets: - - name: amitkumardas-pull-secret volumeClaimTemplates: [] diff --git a/test/integration/framework/fixture.go b/test/integration/framework/fixture.go index 8971375..6bf05e5 100644 --- a/test/integration/framework/fixture.go +++ b/test/integration/framework/fixture.go @@ -35,8 +35,8 @@ import ( const ( // testing involves some amount of wait & retry i.e. polling // these variables are tunables used during polling - defaultWaitTimeout = 15 * time.Second - defaultWaitInterval = 250 * time.Millisecond + defaultWaitTimeout = 60 * time.Second + defaultWaitInterval = 200 * time.Millisecond ) // Fixture is the base structure that various test cases will make use diff --git a/test/integration/framework/helper.go b/test/integration/framework/helper.go index 1ae1dcd..974926f 100644 --- a/test/integration/framework/helper.go +++ b/test/integration/framework/helper.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/ghodss/yaml" + "github.com/pkg/errors" apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -70,7 +71,13 @@ func BuildUnstructuredObjFromJSON( obj := map[string]interface{}{} if err := json.Unmarshal([]byte(jsonStr), &obj); err != nil { - panic(err) + panic( + errors.Wrapf( + err, + "%s:%s:%s: Unmarshal failed: %s", + apiVersion, kind, name, jsonStr, + ), + ) } u := &unstructured.Unstructured{Object: obj} diff --git a/test/integration/generic/ns_crd_uninstall_test.go b/test/integration/generic/clean_uninstall_test.go similarity index 98% rename from test/integration/generic/ns_crd_uninstall_test.go rename to test/integration/generic/clean_uninstall_test.go index 3c66f89..bd65486 100644 --- a/test/integration/generic/ns_crd_uninstall_test.go +++ b/test/integration/generic/clean_uninstall_test.go @@ -32,16 +32,16 @@ import ( k8s "openebs.io/metac/third_party/kubernetes" ) -// TestUnInstallOfNSAndCRDs will verify if GenericController can be +// TestCleanUninstall will verify if GenericController can be // used to implement clean uninstall requirements. // -// A clean uninstall implies when a workload specific namespace +// A clean uninstall implies when a workload specific Namespace // is removed from kubernetes cluster, the associated CRDs and CRs // should get removed from this cluster. This should work even in // the cases where CRs are set with finalizers and the corresponding // controllers i.e. pods are no longer available due to the deletion // of this workload namespace. -func TestUnInstallOfNSAndCRDs(t *testing.T) { +func TestCleanUninstall(t *testing.T) { // namespace to setup GenericController ctlNSNamePrefix := "gctl-test" // name of the GenericController diff --git a/test/integration/generic/crd_apply_delete_test.go b/test/integration/generic/crd_apply_delete_test.go new file mode 100644 index 0000000..68773d3 --- /dev/null +++ b/test/integration/generic/crd_apply_delete_test.go @@ -0,0 +1,300 @@ +/* +Copyright 2019 The MayaData Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generic + +import ( + "testing" + + "github.com/pkg/errors" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/json" + + "openebs.io/metac/apis/metacontroller/v1alpha1" + "openebs.io/metac/controller/generic" + "openebs.io/metac/test/integration/framework" +) + +// TestApplyDeleteCRD will verify if GenericController can be +// used to implement apply & delete of CustomResourceDefinition. +// +// This function will try to get a CRD installed when a target namespace +// gets installed. GenericController should also automatically uninstall +// this CRD when this target namespace is deleted. +func TestApplyDeleteCRD(t *testing.T) { + if testing.Short() { + t.Skip("Skipping TestApplyDeleteCRD in short mode") + } + + // namespace to setup GenericController + ctlNSNamePrefix := "gctl-test" + + // name of the GenericController + ctlName := "install-un-crd-ctrl" + + // name of the target namespace which is watched by GenericController + targetNSName := "amitd" + + // name of the target CRD which is reconciled by GenericController + targetCRDName := "storages.dao.amitd.io" + + f := framework.NewFixture(t) + defer f.TearDown() + + // create namespace to setup GenericController resources + ctlNS := f.CreateNamespaceGen(ctlNSNamePrefix) + + // ------------------------------------------------------------------------- + // Define the "reconcile logic" for sync i.e. create/update events of watch + // ------------------------------------------------------------------------- + // + // NOTE: + // Sync ensures creation of target CRD via attachments + sHook := f.ServeWebhook(func(body []byte) ([]byte, error) { + req := generic.SyncHookRequest{} + if uerr := json.Unmarshal(body, &req); uerr != nil { + return nil, uerr + } + + // initialize the hook response + resp := generic.SyncHookResponse{} + + // we desire this CRD object + crd := framework.BuildUnstructuredObjFromJSON( + "apiextensions.k8s.io/v1beta1", + "CustomResourceDefinition", + targetCRDName, + `{ + "spec": { + "group": "dao.amitd.io", + "version": "v1alpha1", + "scope": "Namespaced", + "names": { + "plural": "storages", + "singular": "storage", + "kind": "Storage", + "shortNames": ["stor"] + }, + "additionalPrinterColumns": [ + { + "JSONPath": ".spec.capacity", + "name": "Capacity", + "description": "Capacity of the storage", + "type": "string" + }, + { + "JSONPath": ".spec.nodeName", + "name": "NodeName", + "description": "Node where the storage gets attached", + "type": "string" + }, + { + "JSONPath": ".status.phase", + "name": "Status", + "description": "Identifies the current status of the storage", + "type": "string" + } + ] + } + }`, + ) + + // add CRD to attachments to let GenericController + // sync i.e. create + resp.Attachments = append(resp.Attachments, crd) + + return json.Marshal(resp) + }) + + // --------------------------------------------------------------------- + // Define the "reconcile logic" for finalize i.e. delete event of watch + // --------------------------------------------------------------------- + // + // NOTE: + // Finalize ensures deletion of target CRD via attachments + fHook := f.ServeWebhook(func(body []byte) ([]byte, error) { + req := generic.SyncHookRequest{} + if uerr := json.Unmarshal(body, &req); uerr != nil { + return nil, uerr + } + + // initialize the hook response + resp := generic.SyncHookResponse{} + + // set attachments to nil to let GenericController + // finalize i.e. delete CRD + resp.Attachments = nil + + // finalize hook should be executed till its request + // has attachments + if req.Attachments.IsEmpty() { + // since all attachments are deleted from cluster + // indicate GenericController to mark completion + // of finalize hook + resp.Finalized = true + } else { + // if there are still attachments seen in the request + // keep resyncing the watch + resp.ResyncAfterSeconds = 2 + } + + t.Logf("Finalize: Req.Attachments.Len=%d", req.Attachments.Len()) + + return json.Marshal(resp) + }) + + // --------------------------------------------------------- + // Define & Apply a GenericController i.e. a Meta Controller + // --------------------------------------------------------- + + // This is one of the meta controller that is defined as + // a Kubernetes custom resource. It listens to the resource + // specified in the watch field and acts against the resources + // specified in the attachments field. + f.CreateGenericController( + ctlName, + ctlNS.Name, + + // set 'sync' as well as 'finalize' hooks + generic.WithWebhookSyncURL(&sHook.URL), + generic.WithWebhookFinalizeURL(&fHook.URL), + + // Namespace is the watched resource + generic.WithWatch( + &v1alpha1.GenericControllerResource{ + ResourceRule: v1alpha1.ResourceRule{ + APIVersion: "v1", + Resource: "namespaces", + }, + // We are interested only for the target namespace only + NameSelector: []string{targetNSName}, + }, + ), + + // CRDs are the attachments + // + // This is done so as to implement create & delete of CRD + // when above watch resource i.e. namespce is created & deleted. + generic.WithAttachments( + []*v1alpha1.GenericControllerAttachment{ + // We want the target CRD only i.e. storages.dao.amitd.io + &v1alpha1.GenericControllerAttachment{ + GenericControllerResource: v1alpha1.GenericControllerResource{ + ResourceRule: v1alpha1.ResourceRule{ + APIVersion: "apiextensions.k8s.io/v1beta1", + Resource: "customresourcedefinitions", + }, + NameSelector: []string{targetCRDName}, + }, + }, + }, + ), + ) + + var err error + + // --------------------------------------------------- + // Create the target namespace i.e. target under test + // --------------------------------------------------- + // + // NOTE: + // This triggers reconciliation + _, err = f.GetTypedClientset().CoreV1().Namespaces().Create( + &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: targetNSName, + }, + }, + ) + if err != nil { + t.Fatal(err) + } + + // Need to wait & see if our controller works as expected + // Make sure the specified attachments i.e. CRD is created + t.Logf("Wait for creation of CRD %s", targetCRDName) + + err = f.Wait(func() (bool, error) { + var getErr error + + // ------------------------------------------------ + // verify if target CRD is created i.e. reconciled + // ------------------------------------------------ + + crdObj, getErr := + f.GetCRDClient().CustomResourceDefinitions().Get(targetCRDName, metav1.GetOptions{}) + + if getErr != nil { + return false, getErr + } + + if crdObj == nil { + return false, errors.Errorf("CRD %s is not created", targetCRDName) + } + + // condition passed + return true, nil + }) + + if err != nil { + t.Fatalf("CRD %s wasn't created: %v", targetCRDName, err) + } + + // ------------------------------------------------------ + // Trigger reconcile again by deleting the target namespace + // ------------------------------------------------------ + + err = + f.GetTypedClientset().CoreV1().Namespaces().Delete(targetNSName, &metav1.DeleteOptions{}) + if err != nil { + t.Fatal(err) + } + + // Need to wait & see if our controller works as expected + // Make sure the specified attachments i.e. CRD is deleted + t.Logf("Wait for deletion of CRD %s", targetCRDName) + + err = f.Wait(func() (bool, error) { + var getErr error + + // ------------------------------------------------ + // verify if target CRD is deleted i.e. reconciled + // ------------------------------------------------ + + crdObj, getErr := + f.GetCRDClient().CustomResourceDefinitions().Get(targetCRDName, metav1.GetOptions{}) + + if getErr != nil && !apierrors.IsNotFound(getErr) { + return false, getErr + } + + if crdObj != nil && crdObj.GetDeletionTimestamp() == nil { + return false, + errors.Errorf("CRD %s is not marked for deletion", targetCRDName) + } + + // condition passed + return true, nil + }) + + if err != nil { + t.Fatalf("CRD %s wasn't deleted: %v", targetCRDName, err) + } + + t.Logf("Test 'Install Uninstall CRD' passed") +} diff --git a/test/integration/generic/generic_test.go b/test/integration/generic/generic_test.go index b7a5c80..6651a16 100644 --- a/test/integration/generic/generic_test.go +++ b/test/integration/generic/generic_test.go @@ -33,18 +33,6 @@ import ( k8s "openebs.io/metac/third_party/kubernetes" ) -// This will be run only once when go test is invoked against this package. -// All the other TestXYZ functions will be invoked via m.Run call only. -// -// framework.TestMain provides setup & teardown features required for -// all the individual testcases to run. -// -// TODO (@amitkumardas): -// Once refactor is done, move this func to suite_test.go -func TestMain(m *testing.M) { - framework.TestMain(m.Run) -} - // TestGCtlSyncWebhook tests that the sync webhook triggers and // passes the request/response properly. func TestGCtlSyncWebhook(t *testing.T) { diff --git a/test/integration/generic/suite_test.go b/test/integration/generic/suite_test.go new file mode 100644 index 0000000..1493f22 --- /dev/null +++ b/test/integration/generic/suite_test.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 The MayaData Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generic + +import ( + "testing" + + "openebs.io/metac/test/integration/framework" +) + +// This will be run only once when go test is invoked against this +// package. All the other Test* functions will be invoked via m.Run +// call. +// +// NOTE: +// framework.TestMain provides setup & teardown features required for +// all the individual testcases to run. +func TestMain(m *testing.M) { + framework.TestMain(m.Run) +}