From b890ef575cadfc74bdedcf8ec2e0a62eef16b584 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Thu, 12 Sep 2019 14:02:10 -0700 Subject: [PATCH 01/32] cmd/operator-sdk/alpha: 'up/down olm' commands to run an operator on a cluster that has OLM installed internal/olm/operator: logic to load an operator bundle into a registry Deployment from a ConfigMap and serve that bundle from an operator-registry server to OLM --- cmd/operator-sdk/alpha/cmd.go | 9 +- cmd/operator-sdk/alpha/down/cmd.go | 30 ++ cmd/operator-sdk/alpha/down/olm/cmd.go | 40 +++ cmd/operator-sdk/alpha/up/cmd.go | 30 ++ cmd/operator-sdk/alpha/up/olm/cmd.go | 40 +++ go.mod | 18 +- go.sum | 73 ++--- hack/tests/alpha-olm-subcommands.sh | 44 ++- internal/olm/operator/internal/configmap.go | 135 ++++++++ internal/olm/operator/internal/deployment.go | 176 ++++++++++ internal/olm/operator/internal/registry.go | 108 +++++++ internal/olm/operator/internal/service.go | 57 ++++ internal/olm/operator/manager.go | 305 ++++++++++++++++++ internal/olm/operator/olm.go | 167 ++++++++++ internal/olm/operator/operator.go | 122 +++++++ internal/util/operator-registry/bundle.go | 152 +++++++++ .../operator-registry/package_manifest.go | 53 --- internal/util/operator-registry/validate.go | 137 ++++++++ ...kage_manifest_test.go => validate_test.go} | 0 19 files changed, 1601 insertions(+), 95 deletions(-) create mode 100644 cmd/operator-sdk/alpha/down/cmd.go create mode 100644 cmd/operator-sdk/alpha/down/olm/cmd.go create mode 100644 cmd/operator-sdk/alpha/up/cmd.go create mode 100644 cmd/operator-sdk/alpha/up/olm/cmd.go create mode 100644 internal/olm/operator/internal/configmap.go create mode 100644 internal/olm/operator/internal/deployment.go create mode 100644 internal/olm/operator/internal/registry.go create mode 100644 internal/olm/operator/internal/service.go create mode 100644 internal/olm/operator/manager.go create mode 100644 internal/olm/operator/olm.go create mode 100644 internal/olm/operator/operator.go create mode 100644 internal/util/operator-registry/bundle.go delete mode 100644 internal/util/operator-registry/package_manifest.go create mode 100644 internal/util/operator-registry/validate.go rename internal/util/operator-registry/{package_manifest_test.go => validate_test.go} (100%) diff --git a/cmd/operator-sdk/alpha/cmd.go b/cmd/operator-sdk/alpha/cmd.go index 31e56acaf1f..78226041933 100644 --- a/cmd/operator-sdk/alpha/cmd.go +++ b/cmd/operator-sdk/alpha/cmd.go @@ -15,7 +15,10 @@ package alpha import ( + "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/down" "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/olm" + "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/up" + "github.com/spf13/cobra" ) @@ -25,6 +28,10 @@ func NewCmd() *cobra.Command { Short: "Run an alpha subcommand", } - cmd.AddCommand(olm.NewCmd()) + cmd.AddCommand( + olm.NewCmd(), + up.NewCmd(), + down.NewCmd(), + ) return cmd } diff --git a/cmd/operator-sdk/alpha/down/cmd.go b/cmd/operator-sdk/alpha/down/cmd.go new file mode 100644 index 00000000000..2b786e1579c --- /dev/null +++ b/cmd/operator-sdk/alpha/down/cmd.go @@ -0,0 +1,30 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package down + +import ( + downolm "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/down/olm" + + "github.com/spf13/cobra" +) + +func NewCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "down", + Short: "Tear down your operator in a Kubernetes cluster", + } + cmd.AddCommand(downolm.NewOLMCmd()) + return cmd +} diff --git a/cmd/operator-sdk/alpha/down/olm/cmd.go b/cmd/operator-sdk/alpha/down/olm/cmd.go new file mode 100644 index 00000000000..5389b0ee3de --- /dev/null +++ b/cmd/operator-sdk/alpha/down/olm/cmd.go @@ -0,0 +1,40 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "fmt" + + olmoperator "github.com/operator-framework/operator-sdk/internal/olm/operator" + + "github.com/spf13/cobra" +) + +func NewOLMCmd() *cobra.Command { + c := &olmoperator.OLMCmd{} + cmd := &cobra.Command{ + Use: "olm", + Short: "Tear down your operator with the Operator Lifecycle Manager", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("command %q requires exactly one argument", cmd.CommandPath()) + } + c.ManifestsDir = args[0] + return c.Down() + }, + } + c.AddToFlagSet(cmd.Flags()) + return cmd +} diff --git a/cmd/operator-sdk/alpha/up/cmd.go b/cmd/operator-sdk/alpha/up/cmd.go new file mode 100644 index 00000000000..c20d1c1c7de --- /dev/null +++ b/cmd/operator-sdk/alpha/up/cmd.go @@ -0,0 +1,30 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package up + +import ( + upolm "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/up/olm" + + "github.com/spf13/cobra" +) + +func NewCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "up", + Short: "Deploy your operator to a Kubernetes cluster", + } + cmd.AddCommand(upolm.NewOLMCmd()) + return cmd +} diff --git a/cmd/operator-sdk/alpha/up/olm/cmd.go b/cmd/operator-sdk/alpha/up/olm/cmd.go new file mode 100644 index 00000000000..40dcf9cdfaa --- /dev/null +++ b/cmd/operator-sdk/alpha/up/olm/cmd.go @@ -0,0 +1,40 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "fmt" + + olmoperator "github.com/operator-framework/operator-sdk/internal/olm/operator" + + "github.com/spf13/cobra" +) + +func NewOLMCmd() *cobra.Command { + c := &olmoperator.OLMCmd{} + cmd := &cobra.Command{ + Use: "olm", + Short: "Deploy your operator with the Operator Lifecycle Manager", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("command %q requires exactly one argument", cmd.CommandPath()) + } + c.ManifestsDir = args[0] + return c.Up() + }, + } + c.AddToFlagSet(cmd.Flags()) + return cmd +} diff --git a/go.mod b/go.mod index 3d578a1b789..f38f522d9a4 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/go-semver v0.2.0 + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/coreos/prometheus-operator v0.29.0 github.com/cyphar/filepath-securejoin v0.2.2 // indirect github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect @@ -23,7 +24,7 @@ require ( github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/camelcase v1.0.0 // indirect - github.com/ghodss/yaml v1.0.0 + github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/go-logr/logr v0.1.0 github.com/go-logr/zapr v0.1.1 github.com/go-openapi/swag v0.19.0 // indirect @@ -32,11 +33,14 @@ require ( github.com/gobwas/glob v0.2.3 // indirect github.com/google/uuid v1.1.1 // indirect github.com/gophercloud/gophercloud v0.0.0-20190408160324-6c7ac67f8855 // indirect + github.com/gorilla/websocket v1.4.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/hashicorp/golang-lru v0.5.1 // indirect github.com/huandu/xstrings v1.2.0 // indirect github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7 github.com/jmoiron/sqlx v1.2.0 // indirect + github.com/jonboulle/clockwork v0.1.0 // indirect github.com/lib/pq v1.1.1 // indirect github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 // indirect github.com/markbates/inflect v1.0.4 @@ -48,16 +52,19 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0-rc1 // indirect github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190128024246-5eb7ae5bdb7a - github.com/operator-framework/operator-registry v1.1.1 + github.com/operator-framework/operator-registry v1.3.0 github.com/pborman/uuid v1.2.0 github.com/pelletier/go-toml v1.3.0 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.8.1 - github.com/prometheus/client_golang v0.9.3 + github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 + github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 // indirect + github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872 // indirect github.com/rogpeppe/go-internal v1.3.0 github.com/rubenv/sql-migrate v0.0.0-20190618074426-f4d34eae5a5c // indirect github.com/sergi/go-diff v1.0.0 github.com/sirupsen/logrus v1.4.2 + github.com/soheilhy/cmux v0.1.4 // indirect github.com/spf13/afero v1.2.2 github.com/spf13/cobra v0.0.5 github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -113,3 +120,8 @@ replace ( ) replace github.com/operator-framework/operator-lifecycle-manager => github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190605231540-b8a4faf68e36 + +// TODO(estroz): change this to point to the main repo once +// https://github.com/operator-framework/operator-registry/pull/86 +// is addressed, and remove entirely on a new release. +replace github.com/operator-framework/operator-registry => github.com/estroz/operator-registry v1.3.1-0.20190912000639-78e83c9070d6 diff --git a/go.sum b/go.sum index a95bdcaf3e6..91a40a1d7d9 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,5 @@ -bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c/go.mod h1:1vhO7Mn/FZMgOgDVGLy5X1mE6rq1HbkBdkF/yj8zkcg= +bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U= +bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.0.0-20160913182117-3b1ae45394a2/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -27,8 +28,6 @@ github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF0 github.com/Masterminds/sprig v0.0.0-20190301161902-9f8fceff796f h1:lGvI8+dm9Y/Qr6BfsbmjAz3iC3iq9+vUQLSKCDROE6s= github.com/Masterminds/sprig v0.0.0-20190301161902-9f8fceff796f/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 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= @@ -38,27 +37,27 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6 h1:uZuxRZCz65cG1o6K/xUqImNcYKtmk9ylqaH0itMSvzA= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/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.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 h1:HD4PLRzjuCVW79mQ0/pdsalOLHJ+FaEoqJLxfltpb2U= github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY= github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -81,10 +80,8 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:NyywMz59neOoVRFDz+ccfKWxn784fiHMDnZSy6T+JXY= 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 h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.7.3-0.20190409004836-2e1cfbca03da h1:9ouQ6UxUR99krN1mfiQP+ygP5mS9YSioeyXD01WcwLA= @@ -95,7 +92,6 @@ github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs= github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f h1:AUj1VoZUfhPhOPHULCQQDnGhRelpFWHMLhQVWDsS0v4= @@ -103,7 +99,8 @@ github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.3+incompatible h1:2OwhVdhtzYUp5P5wuGsVDPagKSRd9JK72sJCHVCXh5g= github.com/emicklei/go-restful v2.9.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful-swagger12 v0.0.0-20170926063155-7524189396c6/go.mod h1:qr0VowGBT4CS4Q8vFF8BSeKz34PuqKGxs/L0IAQA9DQ= +github.com/estroz/operator-registry v1.3.1-0.20190912000639-78e83c9070d6 h1:OOOlsy1ZmNSHPrs0fPIxZJP3oILqMwgpd3H8Aex+Y1s= +github.com/estroz/operator-registry v1.3.1-0.20190912000639-78e83c9070d6/go.mod h1:8XWWRNIzjwFFiAoudavBEpvHZJQY6NOV5BzpHKJ3ClI= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -118,12 +115,14 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= +github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= 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-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 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-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= @@ -131,8 +130,10 @@ github.com/go-logr/zapr v0.1.1 h1:qXBXPDdNncunGs7XeEpsJt8wCjYBygluzfdLO0G5baE= github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= 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= +github.com/go-openapi/analysis v0.17.2 h1:eYp14J1o8TTSCzndHBtsNuckikV1PfZOSnx4BcBeu0c= github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.17.2 h1:azEQ8Fnx0jmtFF2fxsnmd6I0x6rsweUF63qqSO1NmKk= github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= 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= @@ -143,20 +144,22 @@ github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3Hfo github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk= github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.17.2 h1:tEXYu6Xc0pevpzzQx5ghrMN9F7IVpN/+u4iD3rkYE5o= github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.17.2 h1:/ZK67ikFhQAMFFH/aPu2MaGH7QjP4wHBvHYOVIzDAw0= github.com/go-openapi/runtime v0.17.2/go.mod h1:QO936ZXeisByFmZEO1IS1Dqhtf4QV1sYYFtIq6Ld86Q= 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.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4= github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= 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= 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.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.0 h1:Kg7Wl7LkTPlmc393QZQ/5rQadPhi7pBVEMZxyTi0Ii8= github.com/go-openapi/swag v0.19.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/validate v0.17.0 h1:pqoViQz3YLOGIhAmD0N4Lt6pa/3Gnj3ymKqQwq8iS6U= github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -227,8 +230,8 @@ github.com/gophercloud/gophercloud v0.0.0-20190408160324-6c7ac67f8855 h1:3dfUujj github.com/gophercloud/gophercloud v0.0.0-20190408160324-6c7ac67f8855/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190203031600-7a902570cb17 h1:prg2TTpTOcJF1jRWL2zSU1FQNgB0STAFNux8GK82y8k= github.com/gregjones/httpcache v0.0.0-20190203031600-7a902570cb17/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -328,7 +331,6 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m 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 h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= 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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -347,12 +349,16 @@ github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9 github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/operator-framework/go-appr v0.0.0-20180917210448-f2aef88446f2/go.mod h1:YNzwUx1i6C4dXWcffyq3yaIb0rh/K8/OvQ4vG0SNlSw= github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190605231540-b8a4faf68e36 h1:zQykXcFkA+wZm5//RKB7BEzEH7Q0Hwvp8+3HJrG5BD0= github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190605231540-b8a4faf68e36/go.mod h1:HKV3ZB9aOUxRyfM53shoBRtIMP4lg8QRmkW+dmZy+kI= -github.com/operator-framework/operator-marketplace v0.0.0-20190216021216-57300a3ef3ba/go.mod h1:msZSL8pXwzQjB+hU+awVrZQw94IwJi3sNZVD3NoESIs= -github.com/operator-framework/operator-registry v1.1.1 h1:oDIevJvKXFsp7BEb7iJHuLvuhPZYBtIx5oZQ7iSISAs= -github.com/operator-framework/operator-registry v1.1.1/go.mod h1:7D4WEwL+EKti5npUh4/u64DQhawCBRugp8Ql20duUb4= +github.com/otiai10/copy v1.0.1 h1:gtBjD8aq4nychvRZ2CyJvFWAw0aja+VHazDdruZKGZA= +github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776 h1:o59bHXu8Ejas8Kq6pjoVJQ9/neN66SM8AKh6wI42BBs= +github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= +github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= +github.com/otiai10/mint v1.2.4 h1:DxYL0itZyPaR5Z9HILdxSoHx+gNs6Yx+neOGS3IVUk0= +github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -374,26 +380,20 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/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-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872 h1:0aNv3xC7DmQoy1/x1sMh18g+fihWW68LL13i8ao9kl4= +github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 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= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -414,7 +414,6 @@ github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -432,7 +431,6 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50/go.mod h1:1pdIZTAHUz+HDKDVZ++5xg/duPlhKAIzw9qy42CWYp4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -444,8 +442,6 @@ github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245 h1:DNVk+NIkGS github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.1 h1:gmervu+jDMvXTbcHQ0pd2wee85nEoE0BsVyEuzkfK8w= -github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= @@ -489,6 +485,7 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk 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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 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= @@ -557,14 +554,15 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181207222222-4c874b978acb/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 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-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190320215829-36c10c0a621f/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190501045030-23463209683d/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c h1:KfpJVdWhuRqNk4XVXzjXf2KAV4TBEP77SYdFGjeGuIE= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= @@ -597,6 +595,9 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= 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= @@ -625,6 +626,7 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 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-20190409021203-6e4e0e4f393b h1:aBGgKJUM9Hk/3AE8WaZIApnTxG35kbuQba2w+SXqezo= k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8 h1:q1Qvjzs/iEdXF6A1a8H3AKVFDzJNcJn3nXMs6R6qFtA= @@ -662,7 +664,6 @@ k8s.io/kubernetes v1.14.1/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5 h1:VBM/0P5TWxwk+Nw6Z+lAw3DKgO76g90ETOiA6rfLV1Y= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -sigs.k8s.io/controller-runtime v0.1.10/go.mod h1:HFAYoOh6XMV+jKF1UjFwrknPbowfyHEHHRdJMf2jMX8= sigs.k8s.io/controller-runtime v0.2.0 h1:5gL30PXOisGZl+Osi4CmLhvMUj77BO3wJeouKF2va50= sigs.k8s.io/controller-runtime v0.2.0/go.mod h1:ZHqrRDZi3f6BzONcvlUxkqCKgwasGk5FZrnSv9TVZF4= sigs.k8s.io/controller-tools v0.2.0 h1:AmQ/0JKBJAjyAiPAkrAf9QW06jkx2lc5hpxMjamsFpw= diff --git a/hack/tests/alpha-olm-subcommands.sh b/hack/tests/alpha-olm-subcommands.sh index ac951d44434..98ce8e75bdf 100755 --- a/hack/tests/alpha-olm-subcommands.sh +++ b/hack/tests/alpha-olm-subcommands.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash -set -ex - +source hack/lib/test_lib.sh test_version() { local version="$1" @@ -36,5 +35,46 @@ test_version() { echo $commandoutput | grep -F "Successfully uninstalled OLM" } +function test_operator() { + local tmp="$(mktemp -d)" + trap_add "rm -rf $tmp" EXIT + local operator_name="memcached-operator" + local operator_version="0.0.3" + local tf_deploy_dir="test/test-framework/deploy" + cp -a "test/test-framework/deploy/olm-catalog/${operator_name}" "${tmp}/" + find "${tmp}/${operator_name}/" -mindepth 1 -type d \ + -exec cp test/test-framework/deploy/crds/*_crd.yaml {} \; + local manifests_dir="${tmp}/${operator_name}" + local csv_name="${operator_name}.v${operator_version}" + local commandoutput + + # down when no operator is up (should fail). + commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --operator-version "$operator_version" 2>&1 || true) + echo $commandoutput | grep -F "Failed to uninstall operator: no operator with name \\\"${csv_name}\\\" is running" + # up with manifests dir and version. + commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --operator-version "$operator_version" 2>&1) + echo $commandoutput | grep -F "Successfully installed \\\"${csv_name}\\\"" + # up when the operator is already up (should fail). + commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --operator-version "$operator_version" 2>&1 || true) + echo $commandoutput | grep -F "Failed to install operator: an operator with name \\\"${csv_name}\\\" is already running" + # down with manifests dir and version. + commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --operator-version "$operator_version" 2>&1) + echo $commandoutput | grep -F "Successfully uninstalled \\\"${csv_name}\\\"" +} + +set -ex + +# olm install/uninstall test_version "latest" test_version "0.10.1" + +# olm up/down +if ! operator-sdk alpha olm install; then + echo "Failed to install OLM latest before 'olm up/down' test" + exit 1 +fi +test_operator +if ! operator-sdk alpha olm uninstall; then + echo "Failed to uninstall OLM latest after 'olm up/down' test" + exit 1 +fi diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go new file mode 100644 index 00000000000..7b688005c4b --- /dev/null +++ b/internal/olm/operator/internal/configmap.go @@ -0,0 +1,135 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "crypto/md5" + "encoding/base32" + "fmt" + "path" + "strings" + + "github.com/ghodss/yaml" + "github.com/operator-framework/operator-registry/pkg/registry" + "github.com/pkg/errors" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" +) + +func getPackageFileName(name string) string { + return fmt.Sprintf("%s.package.yaml", name) +} + +// hashContents creates a base32-encoded md5 digest of b's bytes. +func hashContents(b []byte) string { + h := md5.New() + h.Write(b) + enc := base32.StdEncoding.WithPadding(base32.NoPadding) + return enc.EncodeToString(h.Sum(nil)) +} + +// getObjectFileName opaquely creates a unique file name based on data in u. +func getObjectFileName(b []byte, name, kind string) string { + digest := hashContents(b) + return fmt.Sprintf("%s.%s.%s.yaml", digest, name, strings.ToLower(kind)) +} + +// createConfigMapBinaryData opaquely creates a set of paths using data in pkg +// and each bundle in bundles, unique by path. These paths are intended to +// be keys in a ConfigMap. +func createConfigMapBinaryData(pkg registry.PackageManifest, bundles []*registry.Bundle) (map[string][]byte, error) { + binaryKeyValues := map[string][]byte{} + pkgBytes, err := yaml.Marshal(pkg) + if err != nil { + return nil, errors.Wrapf(err, "error marshalling bundled package manifest %s", pkg.PackageName) + } + binaryKeyValues[getPackageFileName(pkg.PackageName)] = pkgBytes + for _, bundle := range bundles { + for _, o := range bundle.Objects { + ob, err := yaml.Marshal(o) + if err != nil { + return nil, errors.Wrapf(err, "error marshalling object %s %q", o.GroupVersionKind(), o.GetName()) + } + binaryKeyValues[getObjectFileName(ob, o.GetName(), o.GetKind())] = ob + } + } + return binaryKeyValues, nil +} + +const ( + // The directory containing all manifests for an operator, with the + // package manifest being top-level. + containerManifestsDir = "/registry/manifests" + // The directory containing a flat set of all files from all bundles. + containerOperatorDir = containerManifestsDir + "/operator" +) + +// createVolumeMountPaths opaquely creates a set of paths using data in pkg +// and each bundle in bundles, unique by path. These paths are intended to +// be read by binaries in getDBContainerCmd(). +func createVolumeMountPaths(pkg registry.PackageManifest, bundles []*registry.Bundle) ([]string, error) { + keySet := sets.NewString() + keySet.Insert(path.Join(containerManifestsDir, getPackageFileName(pkg.PackageName))) + for _, bundle := range bundles { + for _, o := range bundle.Objects { + ob, err := yaml.Marshal(o) + if err != nil { + return nil, errors.Wrapf(err, "error marshalling object %s %q", o.GroupVersionKind(), o.GetName()) + } + name := getObjectFileName(ob, o.GetName(), o.GetKind()) + keySet.Insert(path.Join(containerOperatorDir, name)) + } + } + return keySet.List(), nil +} + +func getRegistryConfigMapName(pkgName string) string { + name := formatOperatorNameDNS1123(pkgName) + return fmt.Sprintf("%s-registry-bundles", name) +} + +// withBinaryData returns a function that creates entries in the ConfigMap +// argument's binaryData for each key and []byte value in kvs. +func withBinaryData(kvs map[string][]byte) func(*corev1.ConfigMap) { + return func(cm *corev1.ConfigMap) { + if cm.BinaryData == nil { + cm.BinaryData = map[string][]byte{} + } + for k, v := range kvs { + cm.BinaryData[k] = v + } + } +} + +// newRegistryConfigMap creates a new ConfigMap with a name derived from +// pkgName, the package manifest's packageName, in namespace. opts will +// be applied to the ConfigMap object. +func newRegistryConfigMap(pkgName, namespace string, opts ...func(*corev1.ConfigMap)) *corev1.ConfigMap { + cm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: corev1.SchemeGroupVersion.String(), + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: getRegistryConfigMapName(pkgName), + Namespace: namespace, + }, + } + for _, opt := range opts { + opt(cm) + } + return cm +} diff --git a/internal/olm/operator/internal/deployment.go b/internal/olm/operator/internal/deployment.go new file mode 100644 index 00000000000..ee2533f1093 --- /dev/null +++ b/internal/olm/operator/internal/deployment.go @@ -0,0 +1,176 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "fmt" + "path" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + // The image operator-registry's initializer and registry-server binaries + // are run from. + // QUESTION(estroz): version registry image? + registryBaseImage = "quay.io/openshift/origin-operator-registry:latest" + // The port registry-server will listen on within a container. + registryGRPCPort = 50051 +) + +func getRegistryServerName(pkgName string) string { + name := formatOperatorNameDNS1123(pkgName) + return fmt.Sprintf("%s-registry-server", name) +} + +func getRegistryVolumeName(pkgName string) string { + name := formatOperatorNameDNS1123(pkgName) + return fmt.Sprintf("%s-bundle-db", name) +} + +// getRegistryDeploymentLabels creates a set of labels to identify +// operator-registry Deployment objects. +func getRegistryDeploymentLabels(pkgName string) map[string]string { + return map[string]string{ + "name": getRegistryServerName(pkgName), + "owner": "operator-sdk", + } +} + +// applyToDeploymentPodSpec applies f to dep's pod template spec. +func applyToDeploymentPodSpec(dep *appsv1.Deployment, f func(*corev1.PodSpec)) { + f(&dep.Spec.Template.Spec) +} + +// withRegistryGRPCContainer returns a function that appends a volume with +// name volName containing a reference to a ConfigMap with name cmName to +// the Deployment argument's pod template spec. +func withVolumeConfigMap(volName, cmName string) func(*appsv1.Deployment) { + volume := corev1.Volume{ + Name: volName, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cmName, + }, + }, + }, + } + return func(dep *appsv1.Deployment) { + applyToDeploymentPodSpec(dep, func(spec *corev1.PodSpec) { + spec.Volumes = append(spec.Volumes, volume) + }) + } +} + +// withRegistryGRPCContainer returns a function that appends volumeMounts +// to each container in the Deployment argument's pod template spec. One +// volumeMount is appended for each path in paths from volume with name +// volName, with subPath being the file name of the path. +func withContainerVolumeMounts(volName string, paths []string) func(*appsv1.Deployment) { + volumeMounts := []corev1.VolumeMount{} + for _, p := range paths { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: volName, + MountPath: p, + SubPath: path.Base(p), + }) + } + return func(dep *appsv1.Deployment) { + applyToDeploymentPodSpec(dep, func(spec *corev1.PodSpec) { + for i := range spec.Containers { + spec.Containers[i].VolumeMounts = append(spec.Containers[i].VolumeMounts, volumeMounts...) + } + }) + } +} + +const ( + // Path of the bundle database generated by initializer. + regisryDBName = "bundle.db" + // Path of the log file generated by registry-server. + // TODO(estroz): have this log file in an obvious place, ex. /var/log. + registryLogFile = "termination.log" +) + +// getDBContainerCmd returns a command string that, when run, does two things: +// 1. Runs a database initializer on the manifests in the current working +// directory. +// 2. Runs an operator-registry server serving the bundle database. +// The database must be in the current working directory. +func getDBContainerCmd(dbPath, logPath string) string { + initCmd := fmt.Sprintf("/usr/bin/initializer -o %s", dbPath) + srvCmd := fmt.Sprintf("/usr/bin/registry-server -d %s -t %s", dbPath, logPath) + return fmt.Sprintf("%s && %s", initCmd, srvCmd) +} + +// withRegistryGRPCContainer returns a function that appends a container +// running an operator-registry GRPC server to the Deployment argument's +// pod template spec. +func withRegistryGRPCContainer(pkgName string) func(*appsv1.Deployment) { + container := corev1.Container{ + Name: getRegistryServerName(pkgName), + Image: registryBaseImage, + Command: []string{"/bin/bash"}, + Args: []string{ + "-c", + // TODO(estroz): grab logs and print if error + getDBContainerCmd(regisryDBName, registryLogFile), + }, + Ports: []corev1.ContainerPort{ + {Name: "registry-grpc", ContainerPort: registryGRPCPort}, + }, + } + return func(dep *appsv1.Deployment) { + applyToDeploymentPodSpec(dep, func(spec *corev1.PodSpec) { + spec.Containers = append(spec.Containers, container) + }) + } +} + +// newRegistryDeployment creates a new Deployment with a name derived from +// pkgName, the package manifest's packageName, in namespace. The Deployment +// and replicas are created with labels derived from pkgName. opts will be +// applied to the Deployment object. +func newRegistryDeployment(pkgName, namespace string, opts ...func(*appsv1.Deployment)) *appsv1.Deployment { + var replicas int32 = 1 + dep := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: appsv1.SchemeGroupVersion.String(), + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: getRegistryServerName(pkgName), + Namespace: namespace, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: getRegistryDeploymentLabels(pkgName), + }, + Replicas: &replicas, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: getRegistryDeploymentLabels(pkgName), + }, + }, + }, + } + for _, opt := range opts { + opt(dep) + } + return dep +} diff --git a/internal/olm/operator/internal/registry.go b/internal/olm/operator/internal/registry.go new file mode 100644 index 00000000000..ab26b9873fc --- /dev/null +++ b/internal/olm/operator/internal/registry.go @@ -0,0 +1,108 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "context" + "fmt" + "regexp" + + olmresourceclient "github.com/operator-framework/operator-sdk/internal/olm/client" + registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/validation" +) + +// RegistryResources configures creation/deletion of internal registry-related +// resources. +type RegistryResources struct { + Client *olmresourceclient.Client + Manifests registryutil.ManifestsStore +} + +// FEAT(estroz): allow users to specify labels for registry objects. + +// CreateRegistryManifests creates all registry objects required to serve +// manifests from m.manifests in namespace. +func (m *RegistryResources) CreateRegistryManifests(ctx context.Context, namespace string) error { + pkg := m.Manifests.GetPackageManifest() + pkgName := pkg.PackageName + bundles := m.Manifests.GetBundles() + binaryKeyValues, err := createConfigMapBinaryData(pkg, bundles) + if err != nil { + return errors.Wrap(err, "error creating registry ConfigMap binary data") + } + cm := newRegistryConfigMap(pkgName, namespace, + withBinaryData(binaryKeyValues), + ) + volName := getRegistryVolumeName(pkgName) + volumeMountPaths, err := createVolumeMountPaths(pkg, bundles) + if err != nil { + return errors.Wrap(err, "error creating registry Deployment mount paths") + } + dep := newRegistryDeployment(pkgName, namespace, + withRegistryGRPCContainer(pkgName), + withVolumeConfigMap(volName, cm.GetName()), + withContainerVolumeMounts(volName, volumeMountPaths), + ) + service := newRegistryService(pkgName, namespace, + withTCPPort("grpc", registryGRPCPort), + ) + if err = m.Client.DoCreate(ctx, cm, dep, service); err != nil { + return errors.Wrapf(err, "error creating operator %q registry-server objects", pkgName) + } + depKey := types.NamespacedName{ + Name: dep.GetName(), + Namespace: namespace, + } + log.Infof("Waiting for Deployment %q rollout to complete", depKey) + if err = m.Client.DoRolloutWait(ctx, depKey); err != nil { + return errors.Wrapf(err, "error waiting for Deployment %q to roll out", depKey) + } + return nil +} + +// DeleteRegistryManifests deletes all registry objects serving manifests +// from m.manifests in namespace. +func (m *RegistryResources) DeleteRegistryManifests(ctx context.Context, namespace string) error { + pkgName := m.Manifests.GetPackageManifest().PackageName + cm := newRegistryConfigMap(pkgName, namespace) + dep := newRegistryDeployment(pkgName, namespace) + service := newRegistryService(pkgName, namespace) + err := m.Client.DoDelete(ctx, dep, cm, service) + if err != nil { + return errors.Wrapf(err, "error deleting operator %q registry-server objects", pkgName) + } + return nil +} + +// GetRegistryServiceAddr returns a Service's DNS name + port for a given +// pkgName and namespace. +func GetRegistryServiceAddr(pkgName, namespace string) string { + name := getRegistryServerName(pkgName) + return fmt.Sprintf("%s.%s.svc.cluster.local:%d", name, namespace, registryGRPCPort) +} + +// formatOperatorNameDNS1123 ensures name is DNS1123 label-compliant by +// replacing all non-compliant UTF-8 characters with "-". +func formatOperatorNameDNS1123(name string) string { + if len(validation.IsDNS1123Label(name)) != 0 { + replacer := regexp.MustCompile("[^a-zA-Z0-9]+") + return replacer.ReplaceAllString(name, "-") + } + return name +} diff --git a/internal/olm/operator/internal/service.go b/internal/olm/operator/internal/service.go new file mode 100644 index 00000000000..064815a2f3d --- /dev/null +++ b/internal/olm/operator/internal/service.go @@ -0,0 +1,57 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// withTCPPort returns a function that appends a service port to a Service's +// port list with name and TCP port portNum. +func withTCPPort(name string, portNum int32) func(*corev1.Service) { + return func(service *corev1.Service) { + service.Spec.Ports = append(service.Spec.Ports, corev1.ServicePort{ + Name: name, + Protocol: corev1.ProtocolTCP, + Port: portNum, + TargetPort: intstr.FromInt(int(portNum)), + }) + } +} + +// newRegistryService creates a new Service with a name derived from pkgName +// the package manifest's packageName, in namespace. The Service is created +// with labels derived from pkgName. opts will be applied to the Service object. +func newRegistryService(pkgName, namespace string, opts ...func(*corev1.Service)) *corev1.Service { + service := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + APIVersion: corev1.SchemeGroupVersion.String(), + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: getRegistryServerName(pkgName), + Namespace: namespace, + }, + Spec: corev1.ServiceSpec{ + Selector: getRegistryDeploymentLabels(pkgName), + }, + } + for _, opt := range opts { + opt(service) + } + return service +} diff --git a/internal/olm/operator/manager.go b/internal/olm/operator/manager.go new file mode 100644 index 00000000000..5baf82764f1 --- /dev/null +++ b/internal/olm/operator/manager.go @@ -0,0 +1,305 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "context" + "fmt" + "io/ioutil" + + olmresourceclient "github.com/operator-framework/operator-sdk/internal/olm/client" + opinternal "github.com/operator-framework/operator-sdk/internal/olm/operator/internal" + registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + "github.com/operator-framework/operator-sdk/internal/util/yamlutil" + + olmapiv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-sdk/internal/util/k8sutil" + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/types" +) + +// FEAT(estroz): an operator registry only needs to be created once. Only +// a new subscription needs to be created for operator manifests that exist +// in the registry. Add a --save-registry flag to avoid deleting registry. +// FEAT(estroz): save hash of bundle in registry ConfigMap (or elsewhere?) +// and reload the registry if the hash of on-disk bundle data changes. + +// TODO(estroz): ensure OLM errors are percolated up to the user. + +var Scheme = olmresourceclient.Scheme + +func init() { + if err := apiextv1beta1.AddToScheme(Scheme); err != nil { + log.Fatalf("Failed to add Kubhernetes API extensions v1beta1 types to scheme: %v", err) + } + if err := olmapiv1.AddToScheme(Scheme); err != nil { + log.Fatalf("Failed to add OLM operator API v1 types to scheme: %v", err) + } +} + +type operatorManager struct { + client *olmresourceclient.Client + version string + namespace string + force bool + + olmObjects []runtime.Object + manifests registryutil.ManifestsStore +} + +func (c OLMCmd) newManager() (*operatorManager, error) { + m := &operatorManager{} + rc, ns, err := k8sutil.GetKubeconfigAndNamespace(c.KubeconfigPath) + if err != nil { + return nil, errors.Wrapf(err, "failed to get namespace from kubeconfig %s", c.KubeconfigPath) + } + // TODO(estroz): create ns if ns does not exist (ex. defaultNamespace) + if ns == "" { + ns = defaultNamespace + } + if c.OperatorNamespace == "" { + m.namespace = ns + } else { + m.namespace = c.OperatorNamespace + } + if m.client == nil { + m.client, err = olmresourceclient.ClientForConfig(rc) + if err != nil { + return nil, errors.Wrap(err, "failed to create SDK OLM client") + } + } + for _, path := range c.OLMResourcePaths { + if path != "" { + objs, err := readObjectsFromFile(path) + if err != nil { + return nil, err + } + for _, obj := range objs { + m.olmObjects = append(m.olmObjects, obj) + } + } + } + m.manifests, err = registryutil.ManifestsStoreForDir(c.ManifestsDir) + if err != nil { + return nil, err + } + m.version = c.OperatorVersion + m.force = c.Force + return m, nil +} + +func readObjectsFromFile(path string) (objs []*unstructured.Unstructured, err error) { + b, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + dec := serializer.NewCodecFactory(Scheme).UniversalDeserializer() + scanner := yamlutil.NewYAMLScanner(b) + for scanner.Scan() { + u := unstructured.Unstructured{} + _, _, err := dec.Decode(scanner.Bytes(), nil, &u) + if err != nil { + return nil, errors.Wrapf(err, "failed to decode object from manifest %s", path) + } + objs = append(objs, &u) + } + if scanner.Err() != nil { + return nil, errors.Wrapf(scanner.Err(), "failed to scan manifest %s", path) + } + if len(objs) == 0 { + return nil, errors.Errorf("no objects found in manifest %s", path) + } + return objs, nil +} + +func (m operatorManager) hasCatalogSource() bool { + return m.hasKind(olmapiv1alpha1.CatalogSourceKind) +} + +func (m operatorManager) hasSubscription() bool { + return m.hasKind(olmapiv1alpha1.SubscriptionKind) +} + +func (m operatorManager) hasOperatorGroup() bool { + return m.hasKind(olmapiv1.OperatorGroupKind) +} + +func (m operatorManager) hasKind(kind string) bool { + for _, obj := range m.olmObjects { + if obj.GetObjectKind().GroupVersionKind().Kind == kind { + return true + } + } + return false +} + +func (m *operatorManager) up(ctx context.Context) (err error) { + // Ensure OLM is installed. + olmVer, err := m.client.GetInstalledVersion(ctx) + if err != nil { + return err + } + pkg := m.manifests.GetPackageManifest() + pkgName := pkg.PackageName + bundle, err := m.manifests.GetBundleForVersion(m.version) + if err != nil { + return err + } + csv, err := bundle.ClusterServiceVersion() + if err != nil { + return err + } + if !m.force { + if status := m.status(ctx, bundle.Objects...); status.HasExistingResources() { + return errors.Errorf("an operator with name %q is already running\n%s", pkgName, status) + } + } + + log.Info("Creating resources") + rr := opinternal.RegistryResources{ + Client: m.client, + Manifests: m.manifests, + } + if err = rr.CreateRegistryManifests(ctx, olmresourceclient.OLMNamespace); err != nil { + return errors.Wrap(err, "error registering bundle") + } + if !m.hasCatalogSource() { + registryGRPCAddr := opinternal.GetRegistryServiceAddr(pkgName, olmresourceclient.OLMNamespace) + catsrc := newCatalogSource(pkgName, m.namespace, withGRPC(registryGRPCAddr)) + m.olmObjects = append(m.olmObjects, catsrc) + } + if !m.hasSubscription() { + channel, err := getChannelNameForCSVName(pkg, csv.GetName()) + if err != nil { + return err + } + sub := newSubscription(pkgName, m.namespace, withChannel(channel), + withCatalogSource(getCatalogSourceName(pkgName), m.namespace)) + m.olmObjects = append(m.olmObjects, sub) + } + if !m.hasOperatorGroup() { + // TODO(estroz): check if OG needs to be created in m.namespace first. If + // there is, CSV creation will fail with reason TooManyOperatorGroups. If + // the CSV's installModes don't support the target namespace selection of + // the OG, the CSV will fail with UnsupportedOperatorGroup. Might need to + // check these conditions before creating. + // https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/operatorgroups.md + olmCSV, err := registryutil.BundleCSVToCSV(csv) + if err != nil { + return err + } + targetNamespaces := []string{} + if csvSingleNamespace(olmCSV) || csvOwnNamespace(olmCSV) { + targetNamespaces = append(targetNamespaces, m.namespace) + } + og := newOperatorGroup(pkgName, m.namespace, targetNamespaces...) + m.olmObjects = append(m.olmObjects, og) + } + if err = m.client.DoCreate(ctx, m.olmObjects...); err != nil { + return err + } + nn := types.NamespacedName{ + Name: csv.GetName(), + Namespace: m.namespace, + } + log.Printf("Waiting for ClusterServiceVersion %q to reach 'Succeeded' phase", nn) + if err = m.client.DoCSVWait(ctx, nn); err != nil { + return err + } + + status := m.status(ctx, bundle.Objects...) + if len(status.Resources) != len(bundle.Objects) { + return errors.Errorf("some operator %q resources did not install\n%s", csv.GetName(), status) + } + log.Infof("Successfully installed %q on OLM version %q", csv.GetName(), olmVer) + fmt.Print(status) + + return nil +} + +func (m *operatorManager) down(ctx context.Context) (err error) { + // Ensure OLM is installed. + olmVer, err := m.client.GetInstalledVersion(ctx) + if err != nil { + return err + } + pkg := m.manifests.GetPackageManifest() + pkgName := pkg.PackageName + bundle, err := m.manifests.GetBundleForVersion(m.version) + if err != nil { + return err + } + csv, err := bundle.ClusterServiceVersion() + if err != nil { + return err + } + if !m.force { + if status := m.status(ctx, bundle.Objects...); !status.HasExistingResources() { + return errors.Errorf("no operator with name %q is running", pkgName) + } + } + + log.Info("Deleting resources") + rr := opinternal.RegistryResources{ + Client: m.client, + Manifests: m.manifests, + } + if err = rr.DeleteRegistryManifests(ctx, olmresourceclient.OLMNamespace); err != nil { + return errors.Wrap(err, "error deleting registered bundle") + } + if !m.hasCatalogSource() { + m.olmObjects = append(m.olmObjects, newCatalogSource(pkgName, m.namespace)) + } + if !m.hasSubscription() { + m.olmObjects = append(m.olmObjects, newSubscription(pkgName, m.namespace)) + } + if !m.hasOperatorGroup() { + // TODO(estroz): check if OG was created in m.namespace before deleting. + m.olmObjects = append(m.olmObjects, newOperatorGroup(pkgName, m.namespace)) + } + toDelete := make([]runtime.Object, len(m.olmObjects)) + copy(toDelete, m.olmObjects) + for _, o := range bundle.Objects { + o.SetNamespace(m.namespace) + toDelete = append(toDelete, o) + } + if err = m.client.DoDelete(ctx, toDelete...); err != nil { + return err + } + + status := m.status(ctx, bundle.Objects...) + if status.HasExistingResources() { + return errors.Errorf("operator %q resources still exist\n%s", csv.GetName(), status) + } + log.Infof("Successfully uninstalled %q on OLM version %q", csv.GetName(), olmVer) + + return nil +} + +func (m *operatorManager) status(ctx context.Context, us ...*unstructured.Unstructured) olmresourceclient.Status { + objs := []runtime.Object{} + for _, u := range us { + uc := u.DeepCopy() + uc.SetNamespace(m.namespace) + objs = append(objs, uc) + } + return m.client.GetObjectsStatus(ctx, objs...) +} diff --git a/internal/olm/operator/olm.go b/internal/olm/operator/olm.go new file mode 100644 index 00000000000..07aa70a2eac --- /dev/null +++ b/internal/olm/operator/olm.go @@ -0,0 +1,167 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "fmt" + + olmapiv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-registry/pkg/registry" + "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func getSubscriptionName(pkgName string) string { + return fmt.Sprintf("%s-sub", pkgName) +} + +// getChannelNameForCSVName returns the channel for a given csvName. csvName +// usually has the format "{operator-name}.v{X.Y.Z}". An error is returned if +// no channel with current CSV name csvName is found. +func getChannelNameForCSVName(pkg registry.PackageManifest, csvName string) (registry.PackageChannel, error) { + for _, c := range pkg.Channels { + if c.CurrentCSVName == csvName { + return c, nil + } + } + return registry.PackageChannel{}, errors.Errorf("no channel in package manifest %s exists for CSV %s", pkg.PackageName, csvName) +} + +// withCatalogSource returns a function that sets the Subscription argument's +// target CatalogSource's name and namespace. +func withCatalogSource(csName, csNamespace string) func(*olmapiv1alpha1.Subscription) { + return func(sub *olmapiv1alpha1.Subscription) { + sub.Spec.CatalogSource = csName + sub.Spec.CatalogSourceNamespace = csNamespace + } +} + +// withChannel returns a function that sets the Subscription argument's +// target package channel and starting CSV to those in channel. +func withChannel(channel registry.PackageChannel) func(*olmapiv1alpha1.Subscription) { + return func(sub *olmapiv1alpha1.Subscription) { + sub.Spec.Channel = channel.Name + sub.Spec.StartingCSV = channel.CurrentCSVName + } +} + +// newSubscription creates a new Subscription with a name derived from +// pkgName, the package manifest's packageName, in namespace. opts will +// be applied to the Subscription object. +func newSubscription(pkgName, namespace string, opts ...func(*olmapiv1alpha1.Subscription)) *olmapiv1alpha1.Subscription { + sub := &olmapiv1alpha1.Subscription{ + TypeMeta: metav1.TypeMeta{ + APIVersion: olmapiv1alpha1.SchemeGroupVersion.String(), + Kind: olmapiv1alpha1.SubscriptionKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: getSubscriptionName(pkgName), + Namespace: namespace, + }, + Spec: &olmapiv1alpha1.SubscriptionSpec{ + Package: pkgName, + }, + } + for _, opt := range opts { + opt(sub) + } + return sub +} + +func getCatalogSourceName(pkgName string) string { + return fmt.Sprintf("%s-ocs", pkgName) +} + +// withGRPC returns a function that sets the CatalogSource argument's +// server type to GRPC and address at addr. +func withGRPC(addr string) func(*olmapiv1alpha1.CatalogSource) { + return func(catsrc *olmapiv1alpha1.CatalogSource) { + catsrc.Spec.SourceType = olmapiv1alpha1.SourceTypeGrpc + catsrc.Spec.Address = addr + } +} + +// newCatalogSource creates a new CatalogSource with a name derived from +// pkgName, the package manifest's packageName, in namespace. opts will +// be applied to the CatalogSource object. +func newCatalogSource(pkgName, namespace string, opts ...func(*olmapiv1alpha1.CatalogSource)) *olmapiv1alpha1.CatalogSource { + cs := &olmapiv1alpha1.CatalogSource{ + TypeMeta: metav1.TypeMeta{ + APIVersion: olmapiv1alpha1.SchemeGroupVersion.String(), + Kind: olmapiv1alpha1.CatalogSourceKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: getCatalogSourceName(pkgName), + Namespace: namespace, + }, + Spec: olmapiv1alpha1.CatalogSourceSpec{ + DisplayName: pkgName, + Publisher: "operator-sdk", + }, + } + for _, opt := range opts { + opt(cs) + } + return cs +} + +func getOperatorGroupName(pkgName string) string { + return fmt.Sprintf("%s-og", pkgName) +} + +// csvOwnNamespace returns true if the "SingleNamespace" installMode is +// supported. +func csvSingleNamespace(csv *olmapiv1alpha1.ClusterServiceVersion) bool { + for _, mode := range csv.Spec.InstallModes { + if mode.Type == olmapiv1alpha1.InstallModeTypeSingleNamespace && mode.Supported { + return true + } + } + return false +} + +// csvOwnNamespace returns true if the "OwnNamespace" installMode is supported. +func csvOwnNamespace(csv *olmapiv1alpha1.ClusterServiceVersion) bool { + for _, mode := range csv.Spec.InstallModes { + if mode.Type == olmapiv1alpha1.InstallModeTypeOwnNamespace && mode.Supported { + return true + } + } + return false +} + +// newOperatorGroup creates a new OperatorGroup with a name derived from +// pkgName, the package manifest's packageName, in namespace. targetNamespaces +// can be length 0..N. +func newOperatorGroup(pkgName, namespace string, targetNamespaces ...string) *olmapiv1.OperatorGroup { + og := &olmapiv1.OperatorGroup{ + TypeMeta: metav1.TypeMeta{ + APIVersion: olmapiv1.SchemeGroupVersion.String(), + Kind: "OperatorGroup", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: getOperatorGroupName(pkgName), + Namespace: namespace, + }, + } + // Supports all namespaces. + if len(targetNamespaces) == 0 { + return og + } + // Single namespace. + og.Spec.TargetNamespaces = targetNamespaces + return og +} diff --git a/internal/olm/operator/operator.go b/internal/olm/operator/operator.go new file mode 100644 index 00000000000..7e257a902f9 --- /dev/null +++ b/internal/olm/operator/operator.go @@ -0,0 +1,122 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "context" + "fmt" + "time" + + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + "github.com/spf13/pflag" +) + +// TODO(estroz): figure out a good way to deal with creating scorecard objects +// and injecting proxy container + +const ( + DefaultTimeout = time.Minute * 2 + + defaultNamespace = "default" +) + +// OLMCmd configures deployment and teardown of an operator via an OLM +// installation existing on a cluster. +type OLMCmd struct { + // ManifestsDir is a directory containing a package manifest and N bundles + // of the operator's CSV and CRD's. OperatorVersion can be set to the + // version of the desired operator version's subdir and Up()/Down() will + // deploy the operator version in that subdir. + ManifestsDir string + // OperatorVersion is the version of the operator to deploy. It must be + // a semantic version, ex. 0.0.1. + OperatorVersion string + // OLMResourcePaths are path to manifests of OLM resources that override + // defaults generated by methods of OLMCmd. These manifests can be but are + // not limited to: Subscriptions, CatalogSources, OperatorGroups. + OLMResourcePaths []string + + // KubeconfigPath is the local path to a kubeconfig. This uses well-defined + // default loading rules to load the config if empty. + KubeconfigPath string + // OperatorNamespace is the cluster namespace in which operator resources + // are created. + OperatorNamespace string + // Timeout dictates how long to wait for a REST call to complete. A call + // exceeding Timeout will generate an error. + Timeout time.Duration + // Force forces overwriting/deleting of all resources, including registries, + // respectively + Force bool +} + +func (c *OLMCmd) AddToFlagSet(fs *pflag.FlagSet) { + fs.StringVar(&c.ManifestsDir, "manifests-dir", "", "Directory containing bundled operator manifests") + fs.StringVar(&c.OperatorVersion, "operator-version", "", "Version of operator to deploy") + fs.StringSliceVar(&c.OLMResourcePaths, "resources", nil, "Path to OLM resource manifests, ex. a Subscription. These override defaults generated by up/down") + fs.StringVar(&c.KubeconfigPath, "kubeconfig", "", "Path to kubeconfig") + fs.StringVar(&c.OperatorNamespace, "namespace", "", "Namespace in which to create resources") + fs.DurationVar(&c.Timeout, "timeout", DefaultTimeout, "Time to wait for the command to complete before failing") + fs.BoolVar(&c.Force, "force", false, "Force operator-sdk up/down to overwrite/delete all resources known to the command, respectively") +} + +func (c *OLMCmd) validate() error { + if c.ManifestsDir == "" { + return fmt.Errorf("manifests dir must be set") + } + if c.OperatorVersion == "" { + return fmt.Errorf("operator version must be set") + } + return nil +} + +func (c *OLMCmd) initialize() { + if c.Timeout <= 0 { + c.Timeout = DefaultTimeout + } +} + +func (c *OLMCmd) Up() error { + if err := c.validate(); err != nil { + return errors.Wrapf(err, "validation error") + } + m, err := c.newManager() + if err != nil { + return errors.Wrap(err, "error initializing operator manager") + } + ctx, cancel := context.WithTimeout(context.Background(), c.Timeout) + defer cancel() + if err = m.up(ctx); err != nil { + log.Fatalf("Failed to install operator: %v", err) + } + return nil +} + +func (c *OLMCmd) Down() (err error) { + if err := c.validate(); err != nil { + return errors.Wrapf(err, "validation error") + } + m, err := c.newManager() + if err != nil { + return errors.Wrap(err, "error initializing operator manager") + } + ctx, cancel := context.WithTimeout(context.Background(), c.Timeout) + defer cancel() + if err = m.down(ctx); err != nil { + log.Fatalf("Failed to uninstall operator: %v", err) + } + return nil +} diff --git a/internal/util/operator-registry/bundle.go b/internal/util/operator-registry/bundle.go new file mode 100644 index 00000000000..6a480e15fc9 --- /dev/null +++ b/internal/util/operator-registry/bundle.go @@ -0,0 +1,152 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "encoding/json" + + "github.com/blang/semver" + olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-registry/pkg/registry" + "github.com/operator-framework/operator-registry/pkg/sqlite" + "github.com/pkg/errors" +) + +// manifestsLoad loads a manifests directory from disk. +type manifestsLoad struct { + dir string + pkg registry.PackageManifest + bundles map[string]*registry.Bundle +} + +// Ensure manifestsLoad implements registry.Load. +var _ registry.Load = &manifestsLoad{} + +// populate uses operator-registry's sqlite.NewSQLLoaderForDirectory to load +// l.dir's manifests. Note that this method does not call any functions that +// use SQL drivers. +func (l *manifestsLoad) populate() error { + dl := sqlite.NewSQLLoaderForDirectory(l, l.dir) + if err := dl.Populate(); err != nil { + return errors.Wrapf(err, "error getting bundles from manifests dir %q", l.dir) + } + return nil +} + +// AddOperatorBundle adds a bundle to l. +func (l *manifestsLoad) AddOperatorBundle(bundle *registry.Bundle) error { + csvRaw, err := bundle.ClusterServiceVersion() + if err != nil { + return errors.Wrap(err, "error getting bundle CSV") + } + csvSpec := olmapiv1alpha1.ClusterServiceVersionSpec{} + if err := json.Unmarshal(csvRaw.Spec, &csvSpec); err != nil { + return errors.Wrap(err, "error unmarshaling CSV spec") + } + l.bundles[csvSpec.Version.String()] = bundle + return nil +} + +// AddOperatorBundle adds the package manifest to l. +func (l *manifestsLoad) AddPackageChannels(pkg registry.PackageManifest) error { + l.pkg = pkg + return nil +} + +// ManifestsStore knows how to query for an operator's package manifest and +// related bundles. +type ManifestsStore interface { + // GetPackageManifest returns the ManifestsStore's registry.PackageManifest. + // The returned object is assumed to be valid. + GetPackageManifest() registry.PackageManifest + // GetBundles returns the ManifestsStore's set of registry.Bundle. These + // bundles are unique by CSV version, since only one operator type should + // exist in one manifests dir. + // The returned objects are assumed to be valid. + GetBundles() []*registry.Bundle + // GetBundleForVersion returns the ManifestsStore's registry.Bundle for a + // given version string. An error should be returned if the passed version + // does not exist in the store. + // The returned object is assumed to be valid. + GetBundleForVersion(string) (*registry.Bundle, error) +} + +// manifests implements ManifestsStore +type manifests struct { + pkg registry.PackageManifest + bundles map[string]*registry.Bundle +} + +// ManifestsStoreForDir populates a ManifestsStore from the metadata in dir. +// Each bundle and the package manifest are statically validated, and will +// return an error if any are not valid. +func ManifestsStoreForDir(dir string) (ManifestsStore, error) { + l := &manifestsLoad{ + dir: dir, + bundles: map[string]*registry.Bundle{}, + } + if err := l.populate(); err != nil { + return nil, err + } + if err := ValidatePackageManifest(&l.pkg); err != nil { + return nil, errors.Wrap(err, "error validating package manifest") + } + for _, bundle := range l.bundles { + if err := validateBundle(bundle); err != nil { + return nil, errors.Wrap(err, "error validating bundle") + } + } + return &manifests{ + pkg: l.pkg, + bundles: l.bundles, + }, nil +} + +func (l manifests) GetPackageManifest() registry.PackageManifest { + return l.pkg +} + +func (l manifests) GetBundles() (bundles []*registry.Bundle) { + for _, bundle := range l.bundles { + bundles = append(bundles, bundle) + } + return bundles +} + +func (l manifests) GetBundleForVersion(version string) (*registry.Bundle, error) { + if _, err := semver.Parse(version); err != nil { + return nil, errors.Wrapf(err, "error getting bundle for version %q", version) + } + bundle, ok := l.bundles[version] + if !ok { + return nil, errors.Errorf("bundle for version %q does not exist", version) + } + return bundle, nil +} + +// BundleCSVToCSV converts a registry.ClusterServiceVersion to a +// v1alpha1.ClusterServiceVersion. The returned type will not have a status. +func BundleCSVToCSV(bcsv *registry.ClusterServiceVersion) (*olmapiv1alpha1.ClusterServiceVersion, error) { + spec := olmapiv1alpha1.ClusterServiceVersionSpec{} + if err := json.Unmarshal(bcsv.Spec, &spec); err != nil { + return nil, errors.Wrapf(err, "error converting bundle CSV %q type", bcsv.GetName()) + } + csv := olmapiv1alpha1.ClusterServiceVersion{ + TypeMeta: bcsv.TypeMeta, + ObjectMeta: bcsv.ObjectMeta, + Spec: spec, + } + return &csv, nil +} diff --git a/internal/util/operator-registry/package_manifest.go b/internal/util/operator-registry/package_manifest.go deleted file mode 100644 index 88e2e2f3c8f..00000000000 --- a/internal/util/operator-registry/package_manifest.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2019 The Operator-SDK Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package registry - -import ( - "fmt" - - "github.com/operator-framework/operator-registry/pkg/registry" - "github.com/pkg/errors" -) - -func ValidatePackageManifest(pm *registry.PackageManifest) error { - if pm.PackageName == "" { - return errors.New("package name cannot be empty") - } - if len(pm.Channels) == 0 { - return errors.New("channels cannot be empty") - } - if pm.DefaultChannelName == "" { - return errors.New("default channel cannot be empty") - } - - seen := map[string]struct{}{} - for i, c := range pm.Channels { - if c.Name == "" { - return fmt.Errorf("channel %d name cannot be empty", i) - } - if c.CurrentCSVName == "" { - return fmt.Errorf("channel %s currentCSV cannot be empty", c.Name) - } - if _, ok := seen[c.Name]; ok { - return fmt.Errorf("duplicate package manifest channel name %s; channel names must be unique", c.Name) - } - seen[c.Name] = struct{}{} - } - if _, ok := seen[pm.DefaultChannelName]; !ok { - return fmt.Errorf("default channel %s does not exist in channels", pm.DefaultChannelName) - } - - return nil -} diff --git a/internal/util/operator-registry/validate.go b/internal/util/operator-registry/validate.go new file mode 100644 index 00000000000..2a85a6c84d5 --- /dev/null +++ b/internal/util/operator-registry/validate.go @@ -0,0 +1,137 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-registry/pkg/appregistry" + "github.com/operator-framework/operator-registry/pkg/registry" + "github.com/pkg/errors" + apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" +) + +// ValidatePackageManifest ensures each datum in pkg is valid relative to other +// related data in pkg. +func ValidatePackageManifest(pkg *registry.PackageManifest) error { + if pkg.PackageName == "" { + return errors.New("package name cannot be empty") + } + if len(pkg.Channels) == 0 { + return errors.New("channels cannot be empty") + } + if pkg.DefaultChannelName == "" { + return errors.New("default channel cannot be empty") + } + + seen := map[string]struct{}{} + for i, c := range pkg.Channels { + if c.Name == "" { + return fmt.Errorf("channel %d name cannot be empty", i) + } + if c.CurrentCSVName == "" { + return fmt.Errorf("channel %q currentCSV cannot be empty", c.Name) + } + if _, ok := seen[c.Name]; ok { + return fmt.Errorf("duplicate package manifest channel name %q; channel names must be unique", c.Name) + } + seen[c.Name] = struct{}{} + } + if _, ok := seen[pkg.DefaultChannelName]; !ok { + return fmt.Errorf("default channel %q does not exist in channels", pkg.DefaultChannelName) + } + + return nil +} + +// validateBundle ensures all objects in bundle have the correct data. +// TODO(estroz): remove once operator-verify library is complete. +func validateBundle(bundle *registry.Bundle) (err error) { + bcsv, err := bundle.ClusterServiceVersion() + if err != nil { + return err + } + csv, err := BundleCSVToCSV(bcsv) + if err != nil { + return err + } + crds, err := bundle.CustomResourceDefinitions() + if err != nil { + return err + } + crdMap := map[string]struct{}{} + for _, crd := range crds { + for _, k := range getCRDKeys(crd) { + crdMap[k.String()] = struct{}{} + } + } + // If at least one CSV has an owned CRD it must be present. + if len(csv.Spec.CustomResourceDefinitions.Owned) > 0 && len(crds) == 0 { + return errors.Errorf("bundled CSV has an owned CRD but no CRD's are present in bundle dir") + } + // Ensure all CRD's referenced in each CSV exist in BundleDir. + for _, o := range csv.Spec.CustomResourceDefinitions.Owned { + key := getCRDDescKey(o) + if _, hasCRD := crdMap[key.String()]; !hasCRD { + return errors.Errorf("bundle dir does not contain owned CRD %q from CSV %q", key, csv.GetName()) + } + } + if !hasSupportedInstallMode(csv) { + return errors.Errorf("at least one installMode must be marked \"supported\" in CSV %q", csv.GetName()) + } + return nil +} + +// hasSupportedInstallMode returns true if a csv supports at least one +// installMode. +func hasSupportedInstallMode(csv *olmapiv1alpha1.ClusterServiceVersion) bool { + for _, mode := range csv.Spec.InstallModes { + if mode.Supported { + return true + } + } + return false +} + +// getCRDKeys returns a key uniquely identifying crd. +func getCRDDescKey(crd olmapiv1alpha1.CRDDescription) appregistry.CRDKey { + return appregistry.CRDKey{ + Kind: crd.Kind, + Name: crd.Name, + Version: crd.Version, + } +} + +// getCRDKeys returns a set of keys uniquely identifying crd per version. +// getCRDKeys assumes at least one of spec.version, spec.versions is non-empty. +func getCRDKeys(crd *apiextv1beta1.CustomResourceDefinition) (keys []appregistry.CRDKey) { + if crd.Spec.Version != "" && len(crd.Spec.Versions) == 0 { + return []appregistry.CRDKey{{ + Kind: crd.Spec.Names.Kind, + Name: crd.GetName(), + Version: crd.Spec.Version, + }, + } + } + for _, v := range crd.Spec.Versions { + keys = append(keys, appregistry.CRDKey{ + Kind: crd.Spec.Names.Kind, + Name: crd.GetName(), + Version: v.Name, + }) + } + return keys +} diff --git a/internal/util/operator-registry/package_manifest_test.go b/internal/util/operator-registry/validate_test.go similarity index 100% rename from internal/util/operator-registry/package_manifest_test.go rename to internal/util/operator-registry/validate_test.go From 2da1009a464f2b542b018f390ea58451ec360e2c Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Thu, 12 Sep 2019 15:48:58 -0700 Subject: [PATCH 02/32] fix unit test --- hack/tests/alpha-olm-subcommands.sh | 4 ++-- internal/util/operator-registry/validate_test.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hack/tests/alpha-olm-subcommands.sh b/hack/tests/alpha-olm-subcommands.sh index 98ce8e75bdf..fd3670f80f4 100755 --- a/hack/tests/alpha-olm-subcommands.sh +++ b/hack/tests/alpha-olm-subcommands.sh @@ -50,13 +50,13 @@ function test_operator() { # down when no operator is up (should fail). commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --operator-version "$operator_version" 2>&1 || true) - echo $commandoutput | grep -F "Failed to uninstall operator: no operator with name \\\"${csv_name}\\\" is running" + echo $commandoutput | grep -F "Failed to uninstall operator: no operator with name \\\"${operator_name}\\\" is running" # up with manifests dir and version. commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --operator-version "$operator_version" 2>&1) echo $commandoutput | grep -F "Successfully installed \\\"${csv_name}\\\"" # up when the operator is already up (should fail). commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --operator-version "$operator_version" 2>&1 || true) - echo $commandoutput | grep -F "Failed to install operator: an operator with name \\\"${csv_name}\\\" is already running" + echo $commandoutput | grep -F "Failed to install operator: an operator with name \\\"${operator_name}\\\" is already running" # down with manifests dir and version. commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --operator-version "$operator_version" 2>&1) echo $commandoutput | grep -F "Successfully uninstalled \\\"${csv_name}\\\"" diff --git a/internal/util/operator-registry/validate_test.go b/internal/util/operator-registry/validate_test.go index 94519e9fa8e..a4958afea5b 100644 --- a/internal/util/operator-registry/validate_test.go +++ b/internal/util/operator-registry/validate_test.go @@ -38,7 +38,7 @@ func TestValidatePackageManifest(t *testing.T) { }{ { "default channel does not exist", - true, "default channel baz does not exist in channels", nil, + true, `default channel "baz" does not exist in channels`, nil, }, { "successful validation", @@ -56,7 +56,7 @@ func TestValidatePackageManifest(t *testing.T) { }, { "one channel's CSVName is empty", - true, "channel foo currentCSV cannot be empty", + true, `channel "foo" currentCSV cannot be empty`, func(pm *registry.PackageManifest) { pm.Channels = make([]registry.PackageChannel, 1) copy(pm.Channels, channels) @@ -65,7 +65,7 @@ func TestValidatePackageManifest(t *testing.T) { }, { "duplicate channel name", - true, "duplicate package manifest channel name foo; channel names must be unique", + true, `duplicate package manifest channel name "foo"; channel names must be unique`, func(pm *registry.PackageManifest) { pm.Channels = append(channels, channels...) }, From ea20611b8ca2ca99cb4c97f27eb5ffec648c05fe Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Thu, 12 Sep 2019 18:22:03 -0700 Subject: [PATCH 03/32] remove excessive Deployment mount paths --- internal/olm/operator/internal/configmap.go | 21 -------------------- internal/olm/operator/internal/deployment.go | 4 +--- internal/olm/operator/internal/registry.go | 6 +----- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index 7b688005c4b..27daad13a8f 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -18,7 +18,6 @@ import ( "crypto/md5" "encoding/base32" "fmt" - "path" "strings" "github.com/ghodss/yaml" @@ -26,7 +25,6 @@ import ( "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/sets" ) func getPackageFileName(name string) string { @@ -77,25 +75,6 @@ const ( containerOperatorDir = containerManifestsDir + "/operator" ) -// createVolumeMountPaths opaquely creates a set of paths using data in pkg -// and each bundle in bundles, unique by path. These paths are intended to -// be read by binaries in getDBContainerCmd(). -func createVolumeMountPaths(pkg registry.PackageManifest, bundles []*registry.Bundle) ([]string, error) { - keySet := sets.NewString() - keySet.Insert(path.Join(containerManifestsDir, getPackageFileName(pkg.PackageName))) - for _, bundle := range bundles { - for _, o := range bundle.Objects { - ob, err := yaml.Marshal(o) - if err != nil { - return nil, errors.Wrapf(err, "error marshalling object %s %q", o.GroupVersionKind(), o.GetName()) - } - name := getObjectFileName(ob, o.GetName(), o.GetKind()) - keySet.Insert(path.Join(containerOperatorDir, name)) - } - } - return keySet.List(), nil -} - func getRegistryConfigMapName(pkgName string) string { name := formatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-registry-bundles", name) diff --git a/internal/olm/operator/internal/deployment.go b/internal/olm/operator/internal/deployment.go index ee2533f1093..ced165a55b2 100644 --- a/internal/olm/operator/internal/deployment.go +++ b/internal/olm/operator/internal/deployment.go @@ -16,7 +16,6 @@ package olm import ( "fmt" - "path" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -80,14 +79,13 @@ func withVolumeConfigMap(volName, cmName string) func(*appsv1.Deployment) { // withRegistryGRPCContainer returns a function that appends volumeMounts // to each container in the Deployment argument's pod template spec. One // volumeMount is appended for each path in paths from volume with name -// volName, with subPath being the file name of the path. +// volName. func withContainerVolumeMounts(volName string, paths []string) func(*appsv1.Deployment) { volumeMounts := []corev1.VolumeMount{} for _, p := range paths { volumeMounts = append(volumeMounts, corev1.VolumeMount{ Name: volName, MountPath: p, - SubPath: path.Base(p), }) } return func(dep *appsv1.Deployment) { diff --git a/internal/olm/operator/internal/registry.go b/internal/olm/operator/internal/registry.go index ab26b9873fc..6f2d20c17a4 100644 --- a/internal/olm/operator/internal/registry.go +++ b/internal/olm/operator/internal/registry.go @@ -50,14 +50,10 @@ func (m *RegistryResources) CreateRegistryManifests(ctx context.Context, namespa withBinaryData(binaryKeyValues), ) volName := getRegistryVolumeName(pkgName) - volumeMountPaths, err := createVolumeMountPaths(pkg, bundles) - if err != nil { - return errors.Wrap(err, "error creating registry Deployment mount paths") - } dep := newRegistryDeployment(pkgName, namespace, withRegistryGRPCContainer(pkgName), withVolumeConfigMap(volName, cm.GetName()), - withContainerVolumeMounts(volName, volumeMountPaths), + withContainerVolumeMounts(volName, []string{containerManifestsDir}), ) service := newRegistryService(pkgName, namespace, withTCPPort("grpc", registryGRPCPort), From 7324bfd4b04f6749428dd4ae7c07062b8656564c Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Thu, 12 Sep 2019 18:28:32 -0700 Subject: [PATCH 04/32] reorganize imports, move DNS 1123 label formatter to registry utils --- internal/olm/operator/internal/configmap.go | 4 +++- internal/olm/operator/internal/deployment.go | 6 ++++-- internal/olm/operator/internal/registry.go | 13 +------------ internal/olm/operator/manager.go | 2 +- internal/util/operator-registry/validate.go | 14 ++++++++++++++ 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index 27daad13a8f..5c0a2276afc 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -20,6 +20,8 @@ import ( "fmt" "strings" + registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + "github.com/ghodss/yaml" "github.com/operator-framework/operator-registry/pkg/registry" "github.com/pkg/errors" @@ -76,7 +78,7 @@ const ( ) func getRegistryConfigMapName(pkgName string) string { - name := formatOperatorNameDNS1123(pkgName) + name := registryutil.FormatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-registry-bundles", name) } diff --git a/internal/olm/operator/internal/deployment.go b/internal/olm/operator/internal/deployment.go index ced165a55b2..54f19007688 100644 --- a/internal/olm/operator/internal/deployment.go +++ b/internal/olm/operator/internal/deployment.go @@ -17,6 +17,8 @@ package olm import ( "fmt" + registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -32,12 +34,12 @@ const ( ) func getRegistryServerName(pkgName string) string { - name := formatOperatorNameDNS1123(pkgName) + name := registryutil.FormatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-registry-server", name) } func getRegistryVolumeName(pkgName string) string { - name := formatOperatorNameDNS1123(pkgName) + name := registryutil.FormatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-bundle-db", name) } diff --git a/internal/olm/operator/internal/registry.go b/internal/olm/operator/internal/registry.go index 6f2d20c17a4..c3c215c04b7 100644 --- a/internal/olm/operator/internal/registry.go +++ b/internal/olm/operator/internal/registry.go @@ -17,14 +17,13 @@ package olm import ( "context" "fmt" - "regexp" olmresourceclient "github.com/operator-framework/operator-sdk/internal/olm/client" registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + "github.com/pkg/errors" log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/validation" ) // RegistryResources configures creation/deletion of internal registry-related @@ -92,13 +91,3 @@ func GetRegistryServiceAddr(pkgName, namespace string) string { name := getRegistryServerName(pkgName) return fmt.Sprintf("%s.%s.svc.cluster.local:%d", name, namespace, registryGRPCPort) } - -// formatOperatorNameDNS1123 ensures name is DNS1123 label-compliant by -// replacing all non-compliant UTF-8 characters with "-". -func formatOperatorNameDNS1123(name string) string { - if len(validation.IsDNS1123Label(name)) != 0 { - replacer := regexp.MustCompile("[^a-zA-Z0-9]+") - return replacer.ReplaceAllString(name, "-") - } - return name -} diff --git a/internal/olm/operator/manager.go b/internal/olm/operator/manager.go index 5baf82764f1..1b13ee392ff 100644 --- a/internal/olm/operator/manager.go +++ b/internal/olm/operator/manager.go @@ -21,12 +21,12 @@ import ( olmresourceclient "github.com/operator-framework/operator-sdk/internal/olm/client" opinternal "github.com/operator-framework/operator-sdk/internal/olm/operator/internal" + "github.com/operator-framework/operator-sdk/internal/util/k8sutil" registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" "github.com/operator-framework/operator-sdk/internal/util/yamlutil" olmapiv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-sdk/internal/util/k8sutil" "github.com/pkg/errors" log "github.com/sirupsen/logrus" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" diff --git a/internal/util/operator-registry/validate.go b/internal/util/operator-registry/validate.go index 2a85a6c84d5..dc2c3602fd6 100644 --- a/internal/util/operator-registry/validate.go +++ b/internal/util/operator-registry/validate.go @@ -16,12 +16,14 @@ package registry import ( "fmt" + "regexp" olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/operator-framework/operator-registry/pkg/appregistry" "github.com/operator-framework/operator-registry/pkg/registry" "github.com/pkg/errors" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "k8s.io/apimachinery/pkg/util/validation" ) // ValidatePackageManifest ensures each datum in pkg is valid relative to other @@ -57,6 +59,18 @@ func ValidatePackageManifest(pkg *registry.PackageManifest) error { return nil } +// dns1123LabelRegexp defines the character set allowed in a DNS 1123 label. +var dns1123LabelRegexp = regexp.MustCompile("[^a-zA-Z0-9]+") + +// FormatOperatorNameDNS1123 ensures name is DNS1123 label-compliant by +// replacing all non-compliant UTF-8 characters with "-". +func FormatOperatorNameDNS1123(name string) string { + if len(validation.IsDNS1123Label(name)) != 0 { + return dns1123LabelRegexp.ReplaceAllString(name, "-") + } + return name +} + // validateBundle ensures all objects in bundle have the correct data. // TODO(estroz): remove once operator-verify library is complete. func validateBundle(bundle *registry.Bundle) (err error) { From 17471e59d4c052ee11383bf116043f95dda79560 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Thu, 12 Sep 2019 20:10:15 -0700 Subject: [PATCH 05/32] internal/olm/operator/internal: implement stale registry data check --- internal/olm/operator/internal/configmap.go | 47 ++++++++++++-- internal/olm/operator/manager.go | 71 +++++++++++++++------ 2 files changed, 95 insertions(+), 23 deletions(-) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index 5c0a2276afc..a8603ace7bc 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -15,6 +15,7 @@ package olm import ( + "context" "crypto/md5" "encoding/base32" "fmt" @@ -27,10 +28,40 @@ import ( "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ) -func getPackageFileName(name string) string { - return fmt.Sprintf("%s.package.yaml", name) +// RegistryDataStale checks if manifest data stored in the registry is stale +// by comparing it to manifest data currently managed by m. +func (m *RegistryResources) RegistryDataStale(ctx context.Context, namespace string) (bool, error) { + pkg := m.Manifests.GetPackageManifest() + pkgName := pkg.PackageName + nn := types.NamespacedName{ + Name: getRegistryConfigMapName(pkgName), + Namespace: namespace, + } + configmap := corev1.ConfigMap{} + err := m.Client.KubeClient.Get(ctx, nn, &configmap) + if err != nil { + return false, err + } + // Collect digests of manifests submitted to m. + newData, err := createConfigMapBinaryData(pkg, m.Manifests.GetBundles()) + if err != nil { + return false, errors.Wrap(err, "error creating binary data") + } + // If lengths don't match we have added or removed a file. + if len(newData) != len(configmap.BinaryData) { + return true, nil + } + // Check each binary value's key, which contains a base32-encoded md5 digest + // component, against the new set of manifest keys. + for fileKey := range configmap.BinaryData { + if _, match := newData[fileKey]; !match { + return true, nil + } + } + return false, nil } // hashContents creates a base32-encoded md5 digest of b's bytes. @@ -47,16 +78,22 @@ func getObjectFileName(b []byte, name, kind string) string { return fmt.Sprintf("%s.%s.%s.yaml", digest, name, strings.ToLower(kind)) } +func getPackageFileName(b []byte, name string) string { + digest := hashContents(b) + return fmt.Sprintf("%s.%s.package.yaml", digest, name) +} + // createConfigMapBinaryData opaquely creates a set of paths using data in pkg // and each bundle in bundles, unique by path. These paths are intended to // be keys in a ConfigMap. func createConfigMapBinaryData(pkg registry.PackageManifest, bundles []*registry.Bundle) (map[string][]byte, error) { + pkgName := pkg.PackageName binaryKeyValues := map[string][]byte{} - pkgBytes, err := yaml.Marshal(pkg) + pb, err := yaml.Marshal(pkg) if err != nil { - return nil, errors.Wrapf(err, "error marshalling bundled package manifest %s", pkg.PackageName) + return nil, errors.Wrapf(err, "error marshalling package manifest %s", pkgName) } - binaryKeyValues[getPackageFileName(pkg.PackageName)] = pkgBytes + binaryKeyValues[getPackageFileName(pb, pkgName)] = pb for _, bundle := range bundles { for _, o := range bundle.Objects { ob, err := yaml.Marshal(o) diff --git a/internal/olm/operator/manager.go b/internal/olm/operator/manager.go index 1b13ee392ff..6b39cbd3e82 100644 --- a/internal/olm/operator/manager.go +++ b/internal/olm/operator/manager.go @@ -30,18 +30,13 @@ import ( "github.com/pkg/errors" log "github.com/sirupsen/logrus" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/types" ) -// FEAT(estroz): an operator registry only needs to be created once. Only -// a new subscription needs to be created for operator manifests that exist -// in the registry. Add a --save-registry flag to avoid deleting registry. -// FEAT(estroz): save hash of bundle in registry ConfigMap (or elsewhere?) -// and reload the registry if the hash of on-disk bundle data changes. - // TODO(estroz): ensure OLM errors are percolated up to the user. var Scheme = olmresourceclient.Scheme @@ -174,12 +169,8 @@ func (m *operatorManager) up(ctx context.Context) (err error) { } log.Info("Creating resources") - rr := opinternal.RegistryResources{ - Client: m.client, - Manifests: m.manifests, - } - if err = rr.CreateRegistryManifests(ctx, olmresourceclient.OLMNamespace); err != nil { - return errors.Wrap(err, "error registering bundle") + if err = m.registryUp(ctx, olmresourceclient.OLMNamespace); err != nil { + return err } if !m.hasCatalogSource() { registryGRPCAddr := opinternal.GetRegistryServiceAddr(pkgName, olmresourceclient.OLMNamespace) @@ -235,6 +226,40 @@ func (m *operatorManager) up(ctx context.Context) (err error) { return nil } +func (m *operatorManager) registryUp(ctx context.Context, namespace string) error { + rr := opinternal.RegistryResources{ + Client: m.client, + Manifests: m.manifests, + } + registryStale, err := rr.RegistryDataStale(ctx, namespace) + if err != nil { + if !apierrors.IsNotFound(err) { + return errors.Wrap(err, "error checking registry data") + } + // ConfigMap doesn't exist yet, so create it as usual. + if err = rr.CreateRegistryManifests(ctx, namespace); err != nil { + return errors.Wrap(err, "error registering bundle") + } + return nil + } + if !registryStale && !m.force { + log.Printf("Registry data is current") + return nil + } + if m.force { + log.Printf("Forcefully recreating registry") + } else { + log.Printf("Registry data stale. Recreating registry") + } + if err = rr.DeleteRegistryManifests(ctx, namespace); err != nil { + return errors.Wrap(err, "error deleting registered bundle") + } + if err = rr.CreateRegistryManifests(ctx, namespace); err != nil { + return errors.Wrap(err, "error registering bundle") + } + return nil +} + func (m *operatorManager) down(ctx context.Context) (err error) { // Ensure OLM is installed. olmVer, err := m.client.GetInstalledVersion(ctx) @@ -258,12 +283,8 @@ func (m *operatorManager) down(ctx context.Context) (err error) { } log.Info("Deleting resources") - rr := opinternal.RegistryResources{ - Client: m.client, - Manifests: m.manifests, - } - if err = rr.DeleteRegistryManifests(ctx, olmresourceclient.OLMNamespace); err != nil { - return errors.Wrap(err, "error deleting registered bundle") + if err = m.registryDown(ctx, olmresourceclient.OLMNamespace); err != nil { + return err } if !m.hasCatalogSource() { m.olmObjects = append(m.olmObjects, newCatalogSource(pkgName, m.namespace)) @@ -294,6 +315,20 @@ func (m *operatorManager) down(ctx context.Context) (err error) { return nil } +func (m *operatorManager) registryDown(ctx context.Context, namespace string) error { + rr := opinternal.RegistryResources{ + Client: m.client, + Manifests: m.manifests, + } + if m.force { + log.Printf("Forcefully deleting registry") + if err := rr.DeleteRegistryManifests(ctx, namespace); err != nil { + return errors.Wrap(err, "error deleting registered bundle") + } + } + return nil +} + func (m *operatorManager) status(ctx context.Context, us ...*unstructured.Unstructured) olmresourceclient.Status { objs := []runtime.Object{} for _, u := range us { From fefa15069bf4208b29ee9413bebd05d9c3372195 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 13 Sep 2019 09:45:12 -0700 Subject: [PATCH 06/32] bump test timeout --- hack/tests/alpha-olm-subcommands.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hack/tests/alpha-olm-subcommands.sh b/hack/tests/alpha-olm-subcommands.sh index fd3670f80f4..96859136b2a 100755 --- a/hack/tests/alpha-olm-subcommands.sh +++ b/hack/tests/alpha-olm-subcommands.sh @@ -49,16 +49,16 @@ function test_operator() { local commandoutput # down when no operator is up (should fail). - commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --operator-version "$operator_version" 2>&1 || true) + commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --timeout 3m --operator-version "$operator_version" 2>&1 || true) echo $commandoutput | grep -F "Failed to uninstall operator: no operator with name \\\"${operator_name}\\\" is running" # up with manifests dir and version. - commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --operator-version "$operator_version" 2>&1) + commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --timeout 3m --operator-version "$operator_version" 2>&1) echo $commandoutput | grep -F "Successfully installed \\\"${csv_name}\\\"" # up when the operator is already up (should fail). - commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --operator-version "$operator_version" 2>&1 || true) + commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --timeout 3m --operator-version "$operator_version" 2>&1 || true) echo $commandoutput | grep -F "Failed to install operator: an operator with name \\\"${operator_name}\\\" is already running" # down with manifests dir and version. - commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --operator-version "$operator_version" 2>&1) + commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --timeout 3m --operator-version "$operator_version" 2>&1) echo $commandoutput | grep -F "Successfully uninstalled \\\"${csv_name}\\\"" } From 6c89c939eb616cb1d09408a87fa863614d58a9ed Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 13 Sep 2019 09:58:57 -0700 Subject: [PATCH 07/32] generalize manifests field passed to OLMCmd --- internal/olm/operator/manager.go | 2 +- internal/olm/operator/operator.go | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/internal/olm/operator/manager.go b/internal/olm/operator/manager.go index 6b39cbd3e82..958dab14d2d 100644 --- a/internal/olm/operator/manager.go +++ b/internal/olm/operator/manager.go @@ -81,7 +81,7 @@ func (c OLMCmd) newManager() (*operatorManager, error) { return nil, errors.Wrap(err, "failed to create SDK OLM client") } } - for _, path := range c.OLMResourcePaths { + for _, path := range c.IncludePaths { if path != "" { objs, err := readObjectsFromFile(path) if err != nil { diff --git a/internal/olm/operator/operator.go b/internal/olm/operator/operator.go index 7e257a902f9..7e9a20c9b35 100644 --- a/internal/olm/operator/operator.go +++ b/internal/olm/operator/operator.go @@ -44,10 +44,16 @@ type OLMCmd struct { // OperatorVersion is the version of the operator to deploy. It must be // a semantic version, ex. 0.0.1. OperatorVersion string - // OLMResourcePaths are path to manifests of OLM resources that override - // defaults generated by methods of OLMCmd. These manifests can be but are - // not limited to: Subscriptions, CatalogSources, OperatorGroups. - OLMResourcePaths []string + // IncludePaths are path to manifests of Kubernetes resources that either + // supplement or override defaults generated by methods of OLMCmd. These + // manifests can be but are not limited to: RBAC, Subscriptions, + // CatalogSources, OperatorGroups. + // + // Kinds that are overridden if supplied: + // - CatalogSource + // - Subscription + // - OperatorGroup + IncludePaths []string // KubeconfigPath is the local path to a kubeconfig. This uses well-defined // default loading rules to load the config if empty. @@ -64,9 +70,8 @@ type OLMCmd struct { } func (c *OLMCmd) AddToFlagSet(fs *pflag.FlagSet) { - fs.StringVar(&c.ManifestsDir, "manifests-dir", "", "Directory containing bundled operator manifests") fs.StringVar(&c.OperatorVersion, "operator-version", "", "Version of operator to deploy") - fs.StringSliceVar(&c.OLMResourcePaths, "resources", nil, "Path to OLM resource manifests, ex. a Subscription. These override defaults generated by up/down") + fs.StringSliceVar(&c.IncludePaths, "include", nil, "Path to Kubernetes resource manifests, ex. Role, Subscription. These supplement or override defaults generated by up/down") fs.StringVar(&c.KubeconfigPath, "kubeconfig", "", "Path to kubeconfig") fs.StringVar(&c.OperatorNamespace, "namespace", "", "Namespace in which to create resources") fs.DurationVar(&c.Timeout, "timeout", DefaultTimeout, "Time to wait for the command to complete before failing") From 86f170f9529190eebc06714a27203f5de477bbca Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 17 Sep 2019 09:21:05 -0700 Subject: [PATCH 08/32] handle OperatorGroup's and namespacing correctly --- cmd/operator-sdk/alpha/down/olm/cmd.go | 6 +- cmd/operator-sdk/alpha/up/olm/cmd.go | 6 +- internal/olm/client/client.go | 14 +- internal/olm/operator/internal/deployment.go | 9 +- internal/olm/operator/internal/registry.go | 5 + internal/olm/operator/manager.go | 98 +++++-- internal/olm/operator/olm.go | 92 +++--- internal/olm/operator/operator.go | 50 +++- internal/olm/operator/tenancy.go | 286 +++++++++++++++++++ internal/util/operator-registry/bundle.go | 13 +- internal/util/operator-registry/validate.go | 5 +- 11 files changed, 468 insertions(+), 116 deletions(-) create mode 100644 internal/olm/operator/tenancy.go diff --git a/cmd/operator-sdk/alpha/down/olm/cmd.go b/cmd/operator-sdk/alpha/down/olm/cmd.go index 5389b0ee3de..42e054faccf 100644 --- a/cmd/operator-sdk/alpha/down/olm/cmd.go +++ b/cmd/operator-sdk/alpha/down/olm/cmd.go @@ -16,6 +16,7 @@ package olm import ( "fmt" + "log" olmoperator "github.com/operator-framework/operator-sdk/internal/olm/operator" @@ -32,7 +33,10 @@ func NewOLMCmd() *cobra.Command { return fmt.Errorf("command %q requires exactly one argument", cmd.CommandPath()) } c.ManifestsDir = args[0] - return c.Down() + if err := c.Down(); err != nil { + log.Fatalf("Failed to uninstall operator: %v", err) + } + return nil }, } c.AddToFlagSet(cmd.Flags()) diff --git a/cmd/operator-sdk/alpha/up/olm/cmd.go b/cmd/operator-sdk/alpha/up/olm/cmd.go index 40dcf9cdfaa..15d0f6335f1 100644 --- a/cmd/operator-sdk/alpha/up/olm/cmd.go +++ b/cmd/operator-sdk/alpha/up/olm/cmd.go @@ -16,6 +16,7 @@ package olm import ( "fmt" + "log" olmoperator "github.com/operator-framework/operator-sdk/internal/olm/operator" @@ -32,7 +33,10 @@ func NewOLMCmd() *cobra.Command { return fmt.Errorf("command %q requires exactly one argument", cmd.CommandPath()) } c.ManifestsDir = args[0] - return c.Up() + if err := c.Up(); err != nil { + log.Fatalf("Failed to install operator: %v", err) + } + return nil }, } c.AddToFlagSet(cmd.Flags()) diff --git a/internal/olm/client/client.go b/internal/olm/client/client.go index f9f2f126fe9..5dc1cdecbd8 100644 --- a/internal/olm/client/client.go +++ b/internal/olm/client/client.go @@ -89,11 +89,10 @@ func (c Client) DoCreate(ctx context.Context, objs ...runtime.Object) error { log.Infof(" Creating %s %q", kind, getName(a.GetNamespace(), a.GetName())) err = c.KubeClient.Create(ctx, obj) if err != nil { - if apierrors.IsAlreadyExists(err) { - log.Infof(" %s %q already exists", kind, getName(a.GetNamespace(), a.GetName())) - return nil + if !apierrors.IsAlreadyExists(err) { + return err } - return err + log.Infof(" %s %q already exists", kind, getName(a.GetNamespace(), a.GetName())) } } return nil @@ -109,11 +108,10 @@ func (c Client) DoDelete(ctx context.Context, objs ...runtime.Object) error { log.Infof(" Deleting %s %q", kind, getName(a.GetNamespace(), a.GetName())) err = c.KubeClient.Delete(ctx, obj, client.PropagationPolicy(metav1.DeletePropagationForeground)) if err != nil { - if apierrors.IsNotFound(err) { - log.Infof(" %s %q does not exist", kind, getName(a.GetNamespace(), a.GetName())) - continue + if !apierrors.IsNotFound(err) { + return err } - return err + log.Infof(" %s %q does not exist", kind, getName(a.GetNamespace(), a.GetName())) } } diff --git a/internal/olm/operator/internal/deployment.go b/internal/olm/operator/internal/deployment.go index 54f19007688..ef2d0decce3 100644 --- a/internal/olm/operator/internal/deployment.go +++ b/internal/olm/operator/internal/deployment.go @@ -46,10 +46,13 @@ func getRegistryVolumeName(pkgName string) string { // getRegistryDeploymentLabels creates a set of labels to identify // operator-registry Deployment objects. func getRegistryDeploymentLabels(pkgName string) map[string]string { - return map[string]string{ - "name": getRegistryServerName(pkgName), - "owner": "operator-sdk", + labels := map[string]string{ + "name": getRegistryServerName(pkgName), } + for k, v := range SDKLabels { + labels[k] = v + } + return labels } // applyToDeploymentPodSpec applies f to dep's pod template spec. diff --git a/internal/olm/operator/internal/registry.go b/internal/olm/operator/internal/registry.go index c3c215c04b7..80a3eb40120 100644 --- a/internal/olm/operator/internal/registry.go +++ b/internal/olm/operator/internal/registry.go @@ -26,6 +26,11 @@ import ( "k8s.io/apimachinery/pkg/types" ) +// SDKLabels are used to identify certain operator-sdk resources. +var SDKLabels = map[string]string{ + "owner": "operator-sdk", +} + // RegistryResources configures creation/deletion of internal registry-related // resources. type RegistryResources struct { diff --git a/internal/olm/operator/manager.go b/internal/olm/operator/manager.go index 958dab14d2d..63d01e53adb 100644 --- a/internal/olm/operator/manager.go +++ b/internal/olm/operator/manager.go @@ -39,7 +39,11 @@ import ( // TODO(estroz): ensure OLM errors are percolated up to the user. -var Scheme = olmresourceclient.Scheme +var ( + Scheme = olmresourceclient.Scheme + + defaultNamespace = "default" +) func init() { if err := apiextv1beta1.AddToScheme(Scheme); err != nil { @@ -56,17 +60,21 @@ type operatorManager struct { namespace string force bool - olmObjects []runtime.Object - manifests registryutil.ManifestsStore + installMode olmapiv1alpha1.InstallModeType + installModeNamespaces []string + olmObjects []runtime.Object + manifests registryutil.ManifestsStore } -func (c OLMCmd) newManager() (*operatorManager, error) { - m := &operatorManager{} +func (c *OLMCmd) newManager() (*operatorManager, error) { + m := &operatorManager{ + force: c.Force, + version: c.OperatorVersion, + } rc, ns, err := k8sutil.GetKubeconfigAndNamespace(c.KubeconfigPath) if err != nil { return nil, errors.Wrapf(err, "failed to get namespace from kubeconfig %s", c.KubeconfigPath) } - // TODO(estroz): create ns if ns does not exist (ex. defaultNamespace) if ns == "" { ns = defaultNamespace } @@ -92,12 +100,29 @@ func (c OLMCmd) newManager() (*operatorManager, error) { } } } + // Since a Subscription refers to a CatalogSource, supplying one but + // not the other is an error. + hasSub, hasCatSrc := m.hasSubscription(), m.hasCatalogSource() + if hasSub || hasCatSrc && !(hasSub && hasCatSrc) { + return nil, errors.New("both a CatalogSource and Subscription must be supplied if one is supplied") + } m.manifests, err = registryutil.ManifestsStoreForDir(c.ManifestsDir) if err != nil { return nil, err } - m.version = c.OperatorVersion - m.force = c.Force + if c.InstallMode == "" { + // Default to OwnNamespace. + m.installMode = olmapiv1alpha1.InstallModeTypeOwnNamespace + m.installModeNamespaces = []string{m.namespace} + } else { + m.installMode, m.installModeNamespaces, err = parseInstallModeKV(c.InstallMode) + if err != nil { + return nil, err + } + } + if err := m.installModeCompatible(m.installMode); err != nil { + return nil, err + } return m, nil } @@ -163,7 +188,14 @@ func (m *operatorManager) up(ctx context.Context) (err error) { return err } if !m.force { - if status := m.status(ctx, bundle.Objects...); status.HasExistingResources() { + // Only check CSV here, since other deployed operators/versions may be + // running with shared CRDs. + obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(csv) + if err != nil { + return err + } + u := unstructured.Unstructured{Object: obj} + if status := m.status(ctx, &u); status.HasExistingResources() { return errors.Errorf("an operator with name %q is already running\n%s", pkgName, status) } } @@ -178,33 +210,33 @@ func (m *operatorManager) up(ctx context.Context) (err error) { m.olmObjects = append(m.olmObjects, catsrc) } if !m.hasSubscription() { - channel, err := getChannelNameForCSVName(pkg, csv.GetName()) + channel, err := getChannelForCSVName(pkg, csv.GetName()) if err != nil { return err } - sub := newSubscription(pkgName, m.namespace, withChannel(channel), + sub := newSubscription(csv.GetName(), m.namespace, + withPackageChannel(pkgName, channel), withCatalogSource(getCatalogSourceName(pkgName), m.namespace)) m.olmObjects = append(m.olmObjects, sub) } if !m.hasOperatorGroup() { - // TODO(estroz): check if OG needs to be created in m.namespace first. If - // there is, CSV creation will fail with reason TooManyOperatorGroups. If - // the CSV's installModes don't support the target namespace selection of - // the OG, the CSV will fail with UnsupportedOperatorGroup. Might need to - // check these conditions before creating. - // https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/operatorgroups.md - olmCSV, err := registryutil.BundleCSVToCSV(csv) - if err != nil { + if err = m.operatorGroupUp(ctx); err != nil { return err } - targetNamespaces := []string{} - if csvSingleNamespace(olmCSV) || csvOwnNamespace(olmCSV) { - targetNamespaces = append(targetNamespaces, m.namespace) + } + // Check for Namespace objects and create those first. + namespaces, objects := []runtime.Object{}, []runtime.Object{} + for _, obj := range m.olmObjects { + if obj.GetObjectKind().GroupVersionKind().Kind == "Namespace" { + namespaces = append(namespaces, obj) + } else { + objects = append(objects, obj) } - og := newOperatorGroup(pkgName, m.namespace, targetNamespaces...) - m.olmObjects = append(m.olmObjects, og) } - if err = m.client.DoCreate(ctx, m.olmObjects...); err != nil { + if err = m.client.DoCreate(ctx, namespaces...); err != nil { + return err + } + if err = m.client.DoCreate(ctx, objects...); err != nil { return err } nn := types.NamespacedName{ @@ -226,7 +258,7 @@ func (m *operatorManager) up(ctx context.Context) (err error) { return nil } -func (m *operatorManager) registryUp(ctx context.Context, namespace string) error { +func (m operatorManager) registryUp(ctx context.Context, namespace string) error { rr := opinternal.RegistryResources{ Client: m.client, Manifests: m.manifests, @@ -290,17 +322,19 @@ func (m *operatorManager) down(ctx context.Context) (err error) { m.olmObjects = append(m.olmObjects, newCatalogSource(pkgName, m.namespace)) } if !m.hasSubscription() { - m.olmObjects = append(m.olmObjects, newSubscription(pkgName, m.namespace)) + m.olmObjects = append(m.olmObjects, newSubscription(csv.GetName(), m.namespace)) } if !m.hasOperatorGroup() { - // TODO(estroz): check if OG was created in m.namespace before deleting. - m.olmObjects = append(m.olmObjects, newOperatorGroup(pkgName, m.namespace)) + if err = m.operatorGroupDown(ctx); err != nil { + return err + } } toDelete := make([]runtime.Object, len(m.olmObjects)) copy(toDelete, m.olmObjects) for _, o := range bundle.Objects { - o.SetNamespace(m.namespace) - toDelete = append(toDelete, o) + oc := o.DeepCopy() + oc.SetNamespace(m.namespace) + toDelete = append(toDelete, oc) } if err = m.client.DoDelete(ctx, toDelete...); err != nil { return err @@ -329,6 +363,8 @@ func (m *operatorManager) registryDown(ctx context.Context, namespace string) er return nil } +// TODO(estroz): "status" subcommand +// TODO(estroz): check registry health on each "status" subcommand invokation func (m *operatorManager) status(ctx context.Context, us ...*unstructured.Unstructured) olmresourceclient.Status { objs := []runtime.Object{} for _, u := range us { diff --git a/internal/olm/operator/olm.go b/internal/olm/operator/olm.go index 07aa70a2eac..8c5455c5177 100644 --- a/internal/olm/operator/olm.go +++ b/internal/olm/operator/olm.go @@ -17,6 +17,8 @@ package olm import ( "fmt" + registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + olmapiv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/operator-framework/operator-registry/pkg/registry" @@ -24,14 +26,15 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func getSubscriptionName(pkgName string) string { - return fmt.Sprintf("%s-sub", pkgName) +func getSubscriptionName(csvName string) string { + name := registryutil.FormatOperatorNameDNS1123(csvName) + return fmt.Sprintf("%s-sub", name) } -// getChannelNameForCSVName returns the channel for a given csvName. csvName -// usually has the format "{operator-name}.v{X.Y.Z}". An error is returned if +// getChannelForCSVName returns the channel for a given csvName. csvName +// has the format "{operator-name}.(v)?{X.Y.Z}". An error is returned if // no channel with current CSV name csvName is found. -func getChannelNameForCSVName(pkg registry.PackageManifest, csvName string) (registry.PackageChannel, error) { +func getChannelForCSVName(pkg registry.PackageManifest, csvName string) (registry.PackageChannel, error) { for _, c := range pkg.Channels { if c.CurrentCSVName == csvName { return c, nil @@ -49,31 +52,32 @@ func withCatalogSource(csName, csNamespace string) func(*olmapiv1alpha1.Subscrip } } -// withChannel returns a function that sets the Subscription argument's -// target package channel and starting CSV to those in channel. -func withChannel(channel registry.PackageChannel) func(*olmapiv1alpha1.Subscription) { +// withPackageChannel returns a function that sets the Subscription argument's +// target package, channel, and starting CSV to those in channel. +func withPackageChannel(pkgName string, channel registry.PackageChannel) func(*olmapiv1alpha1.Subscription) { return func(sub *olmapiv1alpha1.Subscription) { + if sub.Spec == nil { + sub.Spec = &olmapiv1alpha1.SubscriptionSpec{} + } + sub.Spec.Package = pkgName sub.Spec.Channel = channel.Name sub.Spec.StartingCSV = channel.CurrentCSVName } } -// newSubscription creates a new Subscription with a name derived from -// pkgName, the package manifest's packageName, in namespace. opts will -// be applied to the Subscription object. -func newSubscription(pkgName, namespace string, opts ...func(*olmapiv1alpha1.Subscription)) *olmapiv1alpha1.Subscription { +// newSubscription creates a new Subscription for a CSV with a name derived +// from csvName, the CSV's objectmeta.name, in namespace. opts will be applied +// to the Subscription object. +func newSubscription(csvName, namespace string, opts ...func(*olmapiv1alpha1.Subscription)) *olmapiv1alpha1.Subscription { sub := &olmapiv1alpha1.Subscription{ TypeMeta: metav1.TypeMeta{ APIVersion: olmapiv1alpha1.SchemeGroupVersion.String(), Kind: olmapiv1alpha1.SubscriptionKind, }, ObjectMeta: metav1.ObjectMeta{ - Name: getSubscriptionName(pkgName), + Name: getSubscriptionName(csvName), Namespace: namespace, }, - Spec: &olmapiv1alpha1.SubscriptionSpec{ - Package: pkgName, - }, } for _, opt := range opts { opt(sub) @@ -82,7 +86,8 @@ func newSubscription(pkgName, namespace string, opts ...func(*olmapiv1alpha1.Sub } func getCatalogSourceName(pkgName string) string { - return fmt.Sprintf("%s-ocs", pkgName) + name := registryutil.FormatOperatorNameDNS1123(pkgName) + return fmt.Sprintf("%s-ocs", name) } // withGRPC returns a function that sets the CatalogSource argument's @@ -118,50 +123,41 @@ func newCatalogSource(pkgName, namespace string, opts ...func(*olmapiv1alpha1.Ca return cs } -func getOperatorGroupName(pkgName string) string { - return fmt.Sprintf("%s-og", pkgName) -} - -// csvOwnNamespace returns true if the "SingleNamespace" installMode is -// supported. -func csvSingleNamespace(csv *olmapiv1alpha1.ClusterServiceVersion) bool { - for _, mode := range csv.Spec.InstallModes { - if mode.Type == olmapiv1alpha1.InstallModeTypeSingleNamespace && mode.Supported { - return true - } - } - return false -} +// General OperatorGroup for operators created with the SDK. +const sdkOperatorGroupName = "operator-sdk-og" -// csvOwnNamespace returns true if the "OwnNamespace" installMode is supported. -func csvOwnNamespace(csv *olmapiv1alpha1.ClusterServiceVersion) bool { - for _, mode := range csv.Spec.InstallModes { - if mode.Type == olmapiv1alpha1.InstallModeTypeOwnNamespace && mode.Supported { - return true +// withGRPC returns a function that sets the OperatorGroup argument's +// targetNamespaces to namespaces. namespaces can be length 0..N; if +// namespaces length is 0, targetNamespaces is set to an empty string, +// indicating a global scope. +func withTargetNamespaces(namespaces ...string) func(*olmapiv1.OperatorGroup) { + return func(og *olmapiv1.OperatorGroup) { + if len(namespaces) == 0 { + // Supports all namespaces. + og.Spec.TargetNamespaces = []string{""} + } else { + og.Spec.TargetNamespaces = namespaces } } - return false } -// newOperatorGroup creates a new OperatorGroup with a name derived from -// pkgName, the package manifest's packageName, in namespace. targetNamespaces -// can be length 0..N. -func newOperatorGroup(pkgName, namespace string, targetNamespaces ...string) *olmapiv1.OperatorGroup { +// newSDKOperatorGroup creates a new OperatorGroup with name +// sdkOperatorGroupName in namespace. opts will be applied to the +// OperatorGroup object. Note that the default OperatorGroup has a global +// scope. +func newSDKOperatorGroup(namespace string, opts ...func(*olmapiv1.OperatorGroup)) *olmapiv1.OperatorGroup { og := &olmapiv1.OperatorGroup{ TypeMeta: metav1.TypeMeta{ APIVersion: olmapiv1.SchemeGroupVersion.String(), - Kind: "OperatorGroup", + Kind: olmapiv1.OperatorGroupKind, }, ObjectMeta: metav1.ObjectMeta{ - Name: getOperatorGroupName(pkgName), + Name: sdkOperatorGroupName, Namespace: namespace, }, } - // Supports all namespaces. - if len(targetNamespaces) == 0 { - return og + for _, opt := range opts { + opt(og) } - // Single namespace. - og.Spec.TargetNamespaces = targetNamespaces return og } diff --git a/internal/olm/operator/operator.go b/internal/olm/operator/operator.go index 7e9a20c9b35..66da5758c1b 100644 --- a/internal/olm/operator/operator.go +++ b/internal/olm/operator/operator.go @@ -17,10 +17,10 @@ package olm import ( "context" "fmt" + "sync" "time" "github.com/pkg/errors" - log "github.com/sirupsen/logrus" "github.com/spf13/pflag" ) @@ -29,8 +29,6 @@ import ( const ( DefaultTimeout = time.Minute * 2 - - defaultNamespace = "default" ) // OLMCmd configures deployment and teardown of an operator via an OLM @@ -54,12 +52,26 @@ type OLMCmd struct { // - Subscription // - OperatorGroup IncludePaths []string + // InstallMode specifies which supported installMode should be used to + // create an OperatorGroup. The format for this field is as follows: + // + // "InstallModeType=ns1{,ns2{, ...}}" + // + // The InstallModeType string passed must be marked as "supported" in the + // CSV being installed. The namespaces passed must exist or be created by + // passing a Namespace manifest to IncludePaths. An empty set of namespaces + // can be used for AllNamespaces. + // The default mode is OwnNamespace, which uses OperatorNamespace or the + // kubeconfig default. + InstallMode string // KubeconfigPath is the local path to a kubeconfig. This uses well-defined // default loading rules to load the config if empty. KubeconfigPath string // OperatorNamespace is the cluster namespace in which operator resources // are created. + // OperatorNamespace must already exist in the cluster or be defined in + // a manifest passed to IncludePaths. OperatorNamespace string // Timeout dictates how long to wait for a REST call to complete. A call // exceeding Timeout will generate an error. @@ -67,13 +79,18 @@ type OLMCmd struct { // Force forces overwriting/deleting of all resources, including registries, // respectively Force bool + + once sync.Once } +var installModeFormat = "InstallModeType=[ns1,ns2[, ...]]" + func (c *OLMCmd) AddToFlagSet(fs *pflag.FlagSet) { fs.StringVar(&c.OperatorVersion, "operator-version", "", "Version of operator to deploy") - fs.StringSliceVar(&c.IncludePaths, "include", nil, "Path to Kubernetes resource manifests, ex. Role, Subscription. These supplement or override defaults generated by up/down") + fs.StringVar(&c.InstallMode, "install-mode", "", "InstallMode to create OperatorGroup with."+fmt.Sprintf(" Format: %s", installModeFormat)) fs.StringVar(&c.KubeconfigPath, "kubeconfig", "", "Path to kubeconfig") fs.StringVar(&c.OperatorNamespace, "namespace", "", "Namespace in which to create resources") + fs.StringSliceVar(&c.IncludePaths, "include", nil, "Path to Kubernetes resource manifests, ex. Role, Subscription. These supplement or override defaults generated by up/down") fs.DurationVar(&c.Timeout, "timeout", DefaultTimeout, "Time to wait for the command to complete before failing") fs.BoolVar(&c.Force, "force", false, "Force operator-sdk up/down to overwrite/delete all resources known to the command, respectively") } @@ -85,16 +102,24 @@ func (c *OLMCmd) validate() error { if c.OperatorVersion == "" { return fmt.Errorf("operator version must be set") } + if c.InstallMode != "" { + if _, _, err := parseInstallModeKV(c.InstallMode); err != nil { + return err + } + } return nil } func (c *OLMCmd) initialize() { - if c.Timeout <= 0 { - c.Timeout = DefaultTimeout - } + c.once.Do(func() { + if c.Timeout <= 0 { + c.Timeout = DefaultTimeout + } + }) } func (c *OLMCmd) Up() error { + c.initialize() if err := c.validate(); err != nil { return errors.Wrapf(err, "validation error") } @@ -104,13 +129,11 @@ func (c *OLMCmd) Up() error { } ctx, cancel := context.WithTimeout(context.Background(), c.Timeout) defer cancel() - if err = m.up(ctx); err != nil { - log.Fatalf("Failed to install operator: %v", err) - } - return nil + return m.up(ctx) } func (c *OLMCmd) Down() (err error) { + c.initialize() if err := c.validate(); err != nil { return errors.Wrapf(err, "validation error") } @@ -120,8 +143,5 @@ func (c *OLMCmd) Down() (err error) { } ctx, cancel := context.WithTimeout(context.Background(), c.Timeout) defer cancel() - if err = m.down(ctx); err != nil { - log.Fatalf("Failed to uninstall operator: %v", err) - } - return nil + return m.down(ctx) } diff --git a/internal/olm/operator/tenancy.go b/internal/olm/operator/tenancy.go new file mode 100644 index 00000000000..511361d9f7a --- /dev/null +++ b/internal/olm/operator/tenancy.go @@ -0,0 +1,286 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package olm + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "os" + "reflect" + "sort" + "strings" + + registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + + olmapiv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// operatorGroupDown handles logic to decide whether the SDK-managed +// OperatorGroup can be created. +// +// Check if an OperatorGroup needs to be created in m.namespace first. If +// there is and another OpreatorGroup is created, CSV installation will fail +// with reason TooManyOperatorGroups. If the CSV's installModes don't support +// the target namespace selection of the OperatorGroup, the CSV will fail +// with UnsupportedOperatorGroup. +// +// https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/operatorgroups.md +func (m *operatorManager) operatorGroupUp(ctx context.Context) error { + og, err := m.getOperatorGroupInNamespace(ctx, m.namespace) + if err != nil { + return err + } + sdkOG := newSDKOperatorGroup(m.namespace, + withTargetNamespaces(m.installModeNamespaces...)) + if og == nil { + m.olmObjects = append(m.olmObjects, sdkOG) + } else { + // An exactly matching set of namespaces is needed to ensure the operator + // is deployed only in namespaces specified by the user. + sort.Strings(og.Status.Namespaces) + sort.Strings(m.installModeNamespaces) + if reflect.DeepEqual(og.Status.Namespaces, m.installModeNamespaces) { + log.Printf(" Using existing OperatorGroup %q in namespace %q", sdkOperatorGroupName, m.namespace) + } else if og.GetName() == sdkOperatorGroupName { + // operator-sdk manages this OperatorGroup, so we can modify it. + ogCSVs, err := m.getCSVsInOperatorGroup(ctx, og.GetName(), m.namespace) + if err != nil { + return err + } + if len(ogCSVs) != 0 { + fmt.Printf("OperatorGroup %q in namespace %q has existing member CSVs. "+ + "You may merge currently selected namespaces (1) with new namespaces (2):\n"+ + "(1) %+q\n(2) %+q\n"+ + "Doing so may transition installed CSVs into a Failed state with reason "+ + "UnsupportedOperatorGroup or have other unwanted side-effects.\n"+ + "Proceed? [y/N] ", og.GetName(), m.namespace, og.Status.Namespaces, + m.installModeNamespaces) + cli := bufio.NewReader(os.Stdin) + resp, err := cli.ReadString('\n') + if err != nil { + return err + } + if resp = strings.TrimSpace(resp); resp != "y" && resp != "Y" { + fmt.Printf("Not merging namespaces. Please modify the existing OperatorGroup "+ + "%q in namespace %q manually, or create this operator in a new namespace.\n", + og.GetName(), m.namespace) + os.Exit(0) + } + // All namespaces are used. + sdkOG.Spec.TargetNamespaces = mergeNamespaces( + sdkOG.Spec.TargetNamespaces, og.Status.Namespaces) + } + // Simple overwrite patch. Use merge patch type to avoid having to + // construct a JSON patch. + data, err := json.Marshal(sdkOG) + if err != nil { + return err + } + patch := client.ConstantPatch(types.MergePatchType, data) + log.Printf(" Patching less permissive OperatorGroup %q in namespace %q", sdkOperatorGroupName, m.namespace) + // Overwrite existing set of namespaces. + err = m.client.KubeClient.Patch(ctx, sdkOG, patch) + if err != nil { + return err + } + } else { + // operator-sdk does not own this OperatorGroup, cannot modify. + return errors.Errorf("existing OperatorGroup %q in namespace %q does not"+ + " select all namespaces in %+q", og.GetName(), m.namespace, m.installModeNamespaces) + } + } + return nil +} + +func mergeNamespaces(set1, set2 []string) (result []string) { + allNS := map[string]struct{}{} + for _, ns := range append(set1, set2...) { + if _, ok := allNS[ns]; !ok { + result = append(result, ns) + allNS[ns] = struct{}{} + } + } + return result +} + +// operatorGroupDown handles logic to decide whether the SDK-managed +// OperatorGroup can be deleted. +func (m *operatorManager) operatorGroupDown(ctx context.Context) error { + // Check if OperatorGroup was created by operator-sdk before + // deleting. We do not want to delete a pre-existing OperatorGroup, or + // one that is used by existing CSVs. + og, err := m.getOperatorGroupInNamespace(ctx, m.namespace) + if err != nil { + return err + } + if og != nil && og.GetName() == sdkOperatorGroupName { + ogCSVs, err := m.getCSVsInOperatorGroup(ctx, sdkOperatorGroupName, m.namespace) + if err != nil { + return err + } + bundle, err := m.manifests.GetBundleForVersion(m.version) + if err != nil { + return err + } + csv, err := bundle.ClusterServiceVersion() + if err != nil { + return err + } + if len(ogCSVs) == 0 || (len(ogCSVs) == 1 && ogCSVs[0].GetName() == csv.GetName()) { + m.olmObjects = append(m.olmObjects, newSDKOperatorGroup(m.namespace)) + } else { + log.Infof(" Existing OperatorGroup %q in namespace %q is used by existing CSVs, skipping delete", og.GetName(), m.namespace) + } + } + return nil +} + +const ( + // Annotation containing a CSV's member OperatorGroup's name. + olmOperatorGroupAnnotation = "olm.operatorGroup" + // Annotation containing a CSV's member OperatorGroup's namespace. + olmOperatorGroupNamespaceAnnotation = "olm.operatorNamespace" +) + +// getCSVsInOperatorGroup gets all CSVs that are members of the OperatorGroup +// in namespace with name ogName. If ogCSVs is empty, no CSVs are members. +func (m operatorManager) getCSVsInOperatorGroup(ctx context.Context, ogName, namespace string) (ogCSVs []*olmapiv1alpha1.ClusterServiceVersion, err error) { + csvs := olmapiv1alpha1.ClusterServiceVersionList{} + opt := client.InNamespace(namespace) + err = m.client.KubeClient.List(ctx, &csvs, opt) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + for _, csv := range csvs.Items { + annotations := csv.GetAnnotations() + if annotations != nil { + csvOGName, ogOK := annotations[olmOperatorGroupAnnotation] + csvOGNamespace, nsOK := annotations[olmOperatorGroupNamespaceAnnotation] + // TODO(estroz): ensure this works for "" (AllNamespaces). + if ogOK && nsOK && csvOGName == ogName && csvOGNamespace == namespace { + ogCSVs = append(ogCSVs, &csv) + } + } + } + return ogCSVs, nil +} + +// installModeCompatible ensures installMode is compatible with the namespaces +// and CSV's installModes being used. +func (m operatorManager) installModeCompatible(installMode olmapiv1alpha1.InstallModeType) error { + err := validateInstallModeWithNamespaces(installMode, m.installModeNamespaces) + if err != nil { + return err + } + if installMode == olmapiv1alpha1.InstallModeTypeOwnNamespace { + if ns := m.installModeNamespaces[0]; ns != m.namespace { + return errors.Errorf("installMode %s namespace %q must match namespace %q", installMode, ns, m.namespace) + } + } + // Ensure CSV supports installMode. + bundle, err := m.manifests.GetBundleForVersion(m.version) + if err != nil { + return err + } + csv, err := bundle.ClusterServiceVersion() + if err != nil { + return err + } + olmCSV := registryutil.MustBundleCSVToCSV(csv) + for _, mode := range olmCSV.Spec.InstallModes { + if mode.Type == installMode && !mode.Supported { + return errors.Errorf("installMode %s not supported in CSV %q", installMode, olmCSV.GetName()) + } + } + return nil +} + +// parseInstallModeKV parses an installMode string of the format +// installModeFormat. +func parseInstallModeKV(raw string) (olmapiv1alpha1.InstallModeType, []string, error) { + modeSplit := strings.Split(raw, "=") + if len(modeSplit) != 2 { + return "", nil, errors.Errorf("installMode string %q is malformatted, must be: %s", raw, installModeFormat) + } + modeStr, namespaceList := modeSplit[0], modeSplit[1] + mode, ok := installModeStrings[modeStr] + if !ok { + return "", nil, errors.Errorf("installMode type string %q is not a valid installMode type", modeStr) + } + namespaces := []string{} + for _, namespace := range strings.Split(strings.Trim(namespaceList, ","), ",") { + namespaces = append(namespaces, namespace) + } + return mode, namespaces, nil +} + +// Mapping of installMode string values to types, for validation. +var installModeStrings = map[string]olmapiv1alpha1.InstallModeType{ + string(olmapiv1alpha1.InstallModeTypeOwnNamespace): olmapiv1alpha1.InstallModeTypeOwnNamespace, + string(olmapiv1alpha1.InstallModeTypeSingleNamespace): olmapiv1alpha1.InstallModeTypeSingleNamespace, + string(olmapiv1alpha1.InstallModeTypeMultiNamespace): olmapiv1alpha1.InstallModeTypeMultiNamespace, + string(olmapiv1alpha1.InstallModeTypeAllNamespaces): olmapiv1alpha1.InstallModeTypeAllNamespaces, +} + +// validateInstallModeWithNamespaces ensures namespaces are valid given mode. +func validateInstallModeWithNamespaces(mode olmapiv1alpha1.InstallModeType, namespaces []string) error { + switch mode { + case olmapiv1alpha1.InstallModeTypeOwnNamespace, olmapiv1alpha1.InstallModeTypeSingleNamespace: + if len(namespaces) != 1 || namespaces[0] == "" { + return errors.Errorf("installMode %s must be passed with exactly one non-empty namespace, have: %+q", mode, namespaces) + } + case olmapiv1alpha1.InstallModeTypeMultiNamespace: + if len(namespaces) < 2 { + return errors.Errorf("installMode %s must be passed with more than one non-empty namespaces, have: %+q", mode, namespaces) + } + case olmapiv1alpha1.InstallModeTypeAllNamespaces: + if len(namespaces) != 1 || namespaces[0] != "" { + return errors.Errorf("installMode %s must be passed with exactly one empty namespace, have: %+q", mode, namespaces) + } + default: + errors.Errorf("installMode %q is not a valid installMode type", mode) + } + return nil +} + +// getOperatorGroupInNamespace gets the OperatorGroup in namespace. Becuase +// there must only be one OperatorGroup per namespace, an error is returned +// if more than one is found. nil is returned if no OperatorGroup exists in +// namespace. +func (m operatorManager) getOperatorGroupInNamespace(ctx context.Context, namespace string) (*olmapiv1.OperatorGroup, error) { + // There must only be one OperatorGroup per namespace, but we should use list. + ogs := olmapiv1.OperatorGroupList{} + err := m.client.KubeClient.List(ctx, &ogs, client.InNamespace(namespace)) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + if apierrors.IsNotFound(err) || len(ogs.Items) == 0 { + return nil, nil + } + // There should never be more than one, but if there is return an error. + if len(ogs.Items) > 1 { + return nil, errors.Errorf("more than one OperatorGroup exists in namespace %q", namespace) + } + currOG := &ogs.Items[0] + return currOG, nil +} diff --git a/internal/util/operator-registry/bundle.go b/internal/util/operator-registry/bundle.go index 6a480e15fc9..6f6a6ddd73a 100644 --- a/internal/util/operator-registry/bundle.go +++ b/internal/util/operator-registry/bundle.go @@ -22,6 +22,7 @@ import ( "github.com/operator-framework/operator-registry/pkg/registry" "github.com/operator-framework/operator-registry/pkg/sqlite" "github.com/pkg/errors" + log "github.com/sirupsen/logrus" ) // manifestsLoad loads a manifests directory from disk. @@ -136,17 +137,19 @@ func (l manifests) GetBundleForVersion(version string) (*registry.Bundle, error) return bundle, nil } -// BundleCSVToCSV converts a registry.ClusterServiceVersion to a +// MustBundleCSVToCSV converts a registry.ClusterServiceVersion bcsv to a // v1alpha1.ClusterServiceVersion. The returned type will not have a status. -func BundleCSVToCSV(bcsv *registry.ClusterServiceVersion) (*olmapiv1alpha1.ClusterServiceVersion, error) { +// MustBundleCSVToCSV will exit if bcsv's Spec is incorrectly formatted, +// since operator-registry should have not been able to parse the CSV +// if it were not. +func MustBundleCSVToCSV(bcsv *registry.ClusterServiceVersion) *olmapiv1alpha1.ClusterServiceVersion { spec := olmapiv1alpha1.ClusterServiceVersionSpec{} if err := json.Unmarshal(bcsv.Spec, &spec); err != nil { - return nil, errors.Wrapf(err, "error converting bundle CSV %q type", bcsv.GetName()) + log.Fatalf("Error converting bundle CSV %q type: %v", bcsv.GetName(), err) } - csv := olmapiv1alpha1.ClusterServiceVersion{ + return &olmapiv1alpha1.ClusterServiceVersion{ TypeMeta: bcsv.TypeMeta, ObjectMeta: bcsv.ObjectMeta, Spec: spec, } - return &csv, nil } diff --git a/internal/util/operator-registry/validate.go b/internal/util/operator-registry/validate.go index dc2c3602fd6..09859b90c36 100644 --- a/internal/util/operator-registry/validate.go +++ b/internal/util/operator-registry/validate.go @@ -78,10 +78,7 @@ func validateBundle(bundle *registry.Bundle) (err error) { if err != nil { return err } - csv, err := BundleCSVToCSV(bcsv) - if err != nil { - return err - } + csv := MustBundleCSVToCSV(bcsv) crds, err := bundle.CustomResourceDefinitions() if err != nil { return err From 11e63dde3e2ab7f449c64285926a44a6d2c6640e Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 17 Sep 2019 17:59:59 -0700 Subject: [PATCH 09/32] use integration test suite instead of subcommand tests --- hack/tests/alpha-olm-subcommands.sh | 29 +-- test/integration/operator_olm_test.go | 99 +++++++++ test/integration/test_suite.go | 284 ++++++++++++++++++++++++++ 3 files changed, 384 insertions(+), 28 deletions(-) create mode 100644 test/integration/operator_olm_test.go create mode 100644 test/integration/test_suite.go diff --git a/hack/tests/alpha-olm-subcommands.sh b/hack/tests/alpha-olm-subcommands.sh index 96859136b2a..c8444d35738 100755 --- a/hack/tests/alpha-olm-subcommands.sh +++ b/hack/tests/alpha-olm-subcommands.sh @@ -35,33 +35,6 @@ test_version() { echo $commandoutput | grep -F "Successfully uninstalled OLM" } -function test_operator() { - local tmp="$(mktemp -d)" - trap_add "rm -rf $tmp" EXIT - local operator_name="memcached-operator" - local operator_version="0.0.3" - local tf_deploy_dir="test/test-framework/deploy" - cp -a "test/test-framework/deploy/olm-catalog/${operator_name}" "${tmp}/" - find "${tmp}/${operator_name}/" -mindepth 1 -type d \ - -exec cp test/test-framework/deploy/crds/*_crd.yaml {} \; - local manifests_dir="${tmp}/${operator_name}" - local csv_name="${operator_name}.v${operator_version}" - local commandoutput - - # down when no operator is up (should fail). - commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --timeout 3m --operator-version "$operator_version" 2>&1 || true) - echo $commandoutput | grep -F "Failed to uninstall operator: no operator with name \\\"${operator_name}\\\" is running" - # up with manifests dir and version. - commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --timeout 3m --operator-version "$operator_version" 2>&1) - echo $commandoutput | grep -F "Successfully installed \\\"${csv_name}\\\"" - # up when the operator is already up (should fail). - commandoutput=$(operator-sdk alpha up olm "$manifests_dir" --timeout 3m --operator-version "$operator_version" 2>&1 || true) - echo $commandoutput | grep -F "Failed to install operator: an operator with name \\\"${operator_name}\\\" is already running" - # down with manifests dir and version. - commandoutput=$(operator-sdk alpha down olm "$manifests_dir" --timeout 3m --operator-version "$operator_version" 2>&1) - echo $commandoutput | grep -F "Successfully uninstalled \\\"${csv_name}\\\"" -} - set -ex # olm install/uninstall @@ -73,7 +46,7 @@ if ! operator-sdk alpha olm install; then echo "Failed to install OLM latest before 'olm up/down' test" exit 1 fi -test_operator +go test -v ./test/integration/... if ! operator-sdk alpha olm uninstall; then echo "Failed to uninstall OLM latest after 'olm up/down' test" exit 1 diff --git a/test/integration/operator_olm_test.go b/test/integration/operator_olm_test.go new file mode 100644 index 00000000000..5c4cc359a4f --- /dev/null +++ b/test/integration/operator_olm_test.go @@ -0,0 +1,99 @@ +// Copyright 2018 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package e2e + +import ( + "io/ioutil" + "os" + "testing" + + operator "github.com/operator-framework/operator-sdk/internal/olm/operator" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" +) + +func TestOLMIntegration(t *testing.T) { + t.Run("Operator", func(t *testing.T) { + t.Run("Single", SingleOperator) + }) +} + +func SingleOperator(t *testing.T) { + csvConfig := CSVTemplateConfig{ + OperatorName: "memcached-operator", + OperatorVersion: "0.0.2", + TestImageTag: defaultTestImageTag, + Maturity: "alpha", + ReplacesCSVName: "", + CRDKeys: []DefinitionKey{ + { + Kind: "Memcached", + Name: "memcacheds.cache.example.com", + Group: "cache.example.com", + Versions: []v1beta1.CustomResourceDefinitionVersion{ + {Name: "v1alpha1", Storage: true, Served: true}, + }, + }, + }, + InstallModes: []v1alpha1.InstallMode{ + {Type: v1alpha1.InstallModeTypeOwnNamespace, Supported: true}, + {Type: v1alpha1.InstallModeTypeSingleNamespace, Supported: true}, + {Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: false}, + {Type: v1alpha1.InstallModeTypeAllNamespaces, Supported: true}, + }, + } + tmp, err := ioutil.TempDir("", "sdk-integration.") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmp) + defaultChannel := "alpha" + operatorName := "memcached-operator" + operatorVersion := "0.0.2" + manifestsDir, err := writeOperatorManifests(tmp, operatorName, defaultChannel, csvConfig) + if err != nil { + t.Fatal(err) + } + opcmd := operator.OLMCmd{ + ManifestsDir: manifestsDir, + OperatorVersion: operatorVersion, + KubeconfigPath: KubeconfigPath, + } + cases := []struct { + description string + op func() error + force bool + wantErr bool + }{ + {"Remove operator before deploy", opcmd.Down, false, true}, + {"Deploy operator", opcmd.Up, false, false}, + {"Deploy operator after deploy", opcmd.Up, false, true}, + {"Deploy operator after deploy with force", opcmd.Up, true, false}, + {"Remove operator after deploy", opcmd.Down, false, false}, + {"Remove operator after removal", opcmd.Down, false, true}, + {"Remove operator after removal with force", opcmd.Down, true, false}, + } + + for _, c := range cases { + opcmd.Force = c.force + err := c.op() + if c.wantErr && err == nil { + t.Fatalf("%s (%s): wanted error, got: nil", c.description, operatorName) + } else if !c.wantErr && err != nil { + t.Fatalf("%s (%s): wanted no error, got: %v", c.description, operatorName, err) + } + } +} diff --git a/test/integration/test_suite.go b/test/integration/test_suite.go new file mode 100644 index 00000000000..3119398251a --- /dev/null +++ b/test/integration/test_suite.go @@ -0,0 +1,284 @@ +// Copyright 2018 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package e2e + +import ( + "fmt" + "html/template" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" + + "github.com/ghodss/yaml" + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-registry/pkg/registry" + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + defaultTimeout = 2 * time.Minute + defaultTestImageTag = "quay.io/example/test:latest" +) + +var ( + KubeconfigPath = os.Getenv("KUBECONFIG") +) + +type DefinitionKey struct { + Kind string + Name string + Group string + Versions []v1beta1.CustomResourceDefinitionVersion +} + +type CSVTemplateConfig struct { + OperatorName string + OperatorVersion string + TestImageTag string + Maturity string + ReplacesCSVName string + CRDKeys []DefinitionKey + InstallModes []v1alpha1.InstallMode +} + +const csvTmpl = `apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + capabilities: Basic Install + name: {{ .OperatorName }}.v{{ .OperatorVersion }} + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: +{{- range $i, $crd := .CRDKeys }}{{- range $j, $version := $crd.Versions }} + - description: Represents a cluster of {{ $crd.Kind }} apps + displayName: {{ $crd.Kind }} App + kind: {{ $crd.Kind }} + name: {{ $crd.Name }} + resources: + - kind: Deployment + version: v1 + - kind: ReplicaSet + version: v1 + - kind: Pod + version: v1 + specDescriptors: + - description: The desired number of member Pods for the deployment. + displayName: Size + path: size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podCount + statusDescriptors: + - description: The current status of the application. + displayName: Status + path: phase + x-descriptors: + - urn:alm:descriptor:io.kubernetes.phase + - description: Explanation for the current status of the application. + displayName: Status Details + path: reason + x-descriptors: + - urn:alm:descriptor:io.kubernetes.phase:reason + version: {{ $version.Name }} +{{- end }}{{- end }} + description: Big ol' Operator. + displayName: {{ .OperatorName }} Application + install: + spec: + deployments: + - name: {{ .OperatorName }} + spec: + replicas: 1 + selector: + matchLabels: + name: {{ .OperatorName }} + strategy: {} + template: + metadata: + labels: + name: {{ .OperatorName }} + spec: + containers: + - command: + - {{ .OperatorName }} + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: {{ .OperatorName }} + image: {{ .TestImageTag }} + imagePullPolicy: Never + name: {{ .OperatorName }} + resources: {} + serviceAccountName: {{ .OperatorName }} + permissions: + - rules: + - apiGroups: + - "" + resources: + - pods + - services + - endpoints + - persistentvolumeclaims + - events + - configmaps + - secrets + verbs: + - '*' + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - apps + resources: + - deployments + - daemonsets + - replicasets + - statefulsets + verbs: + - '*' + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - apps + resourceNames: + - {{ .OperatorName }} + resources: + - deployments/finalizers + verbs: + - update + serviceAccountName: {{ .OperatorName }} + strategy: deployment + installModes: +{{- range $i, $mode := .InstallModes }} + - supported: {{ $mode.Supported }} + type: {{ $mode.Type }} +{{- end }} + keywords: + - big + - ol + - operator + maintainers: + - email: corp@example.com + name: Some Corp + maturity: {{ .Maturity }} + provider: + name: Example + url: www.example.com +{{- if .ReplacesCSVName }} + replaces: {{ .ReplacesCSVName }} +{{- end }} + version: {{ .OperatorVersion }} +` + +func writeOperatorManifests(root, operatorName, defaultChannel string, csvConfigs ...CSVTemplateConfig) (manifestsDir string, err error) { + manifestsDir = filepath.Join(root, operatorName) + pkg := registry.PackageManifest{ + PackageName: operatorName, + DefaultChannelName: defaultChannel, + } + for _, csvConfig := range csvConfigs { + pkg.Channels = append(pkg.Channels, registry.PackageChannel{ + Name: csvConfig.Maturity, + CurrentCSVName: fmt.Sprintf("%s.v%s", csvConfig.OperatorName, csvConfig.OperatorVersion), + }) + bundleDir := filepath.Join(manifestsDir, csvConfig.OperatorVersion) + for _, key := range csvConfig.CRDKeys { + crd := v1beta1.CustomResourceDefinition{ + TypeMeta: v1.TypeMeta{ + APIVersion: v1beta1.SchemeGroupVersion.String(), + Kind: "CustomResourceDefinition", + }, + ObjectMeta: v1.ObjectMeta{Name: key.Name}, + Spec: v1beta1.CustomResourceDefinitionSpec{ + Names: v1beta1.CustomResourceDefinitionNames{ + Kind: key.Kind, + ListKind: key.Kind + "List", + Singular: strings.ToLower(key.Kind), + Plural: strings.ToLower(key.Kind) + "s", + }, + Group: key.Group, + Scope: "Namespaced", + Versions: key.Versions, + }, + } + crdPath := filepath.Join(bundleDir, fmt.Sprintf("%s.crd.yaml", key.Name)) + if err = writeObjectManifest(crdPath, crd); err != nil { + return "", err + } + } + csvPath := filepath.Join(bundleDir, fmt.Sprintf("%s.v%s.csv.yaml", csvConfig.OperatorName, csvConfig.OperatorVersion)) + if err = execTemplateOnFile(csvPath, csvTmpl, csvConfig); err != nil { + return "", err + } + } + pkgPath := filepath.Join(manifestsDir, fmt.Sprintf("%s.package.yaml", operatorName)) + if err = writeObjectManifest(pkgPath, pkg); err != nil { + return "", err + } + return manifestsDir, nil +} + +func writeObjectManifest(path string, o interface{}) error { + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + b, err := yaml.Marshal(o) + if err != nil { + return err + } + if err = ioutil.WriteFile(path, b, 0644); err != nil { + return err + } + return nil +} + +func execTemplateOnFile(path, tmpl string, o interface{}) error { + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + w, err := os.Create(path) + if err != nil { + return err + } + defer w.Close() + csvTmpl, err := template.New(path).Parse(tmpl) + if err != nil { + return err + } + if err = csvTmpl.Execute(w, o); err != nil { + return err + } + return nil +} From e62ca67469bf1d9882ce6c439ad3796ea22f4f90 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 17 Sep 2019 18:11:51 -0700 Subject: [PATCH 10/32] fix up tests --- internal/olm/operator/internal/configmap.go | 2 +- internal/olm/operator/internal/deployment.go | 8 ++++---- internal/olm/operator/operator.go | 6 +++--- test/integration/test_suite.go | 5 ++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index a8603ace7bc..86f0931d410 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -72,7 +72,7 @@ func hashContents(b []byte) string { return enc.EncodeToString(h.Sum(nil)) } -// getObjectFileName opaquely creates a unique file name based on data in u. +// getObjectFileName opaquely creates a unique file name based on data in b. func getObjectFileName(b []byte, name, kind string) string { digest := hashContents(b) return fmt.Sprintf("%s.%s.%s.yaml", digest, name, strings.ToLower(kind)) diff --git a/internal/olm/operator/internal/deployment.go b/internal/olm/operator/internal/deployment.go index ef2d0decce3..98038b6d7c9 100644 --- a/internal/olm/operator/internal/deployment.go +++ b/internal/olm/operator/internal/deployment.go @@ -60,9 +60,9 @@ func applyToDeploymentPodSpec(dep *appsv1.Deployment, f func(*corev1.PodSpec)) { f(&dep.Spec.Template.Spec) } -// withRegistryGRPCContainer returns a function that appends a volume with -// name volName containing a reference to a ConfigMap with name cmName to -// the Deployment argument's pod template spec. +// withVolumeConfigMap returns a function that appends a volume with name +// volName containing a reference to a ConfigMap with name cmName to the +// Deployment argument's pod template spec. func withVolumeConfigMap(volName, cmName string) func(*appsv1.Deployment) { volume := corev1.Volume{ Name: volName, @@ -81,7 +81,7 @@ func withVolumeConfigMap(volName, cmName string) func(*appsv1.Deployment) { } } -// withRegistryGRPCContainer returns a function that appends volumeMounts +// withContainerVolumeMounts returns a function that appends volumeMounts // to each container in the Deployment argument's pod template spec. One // volumeMount is appended for each path in paths from volume with name // volName. diff --git a/internal/olm/operator/operator.go b/internal/olm/operator/operator.go index 66da5758c1b..3afc5ecd8cb 100644 --- a/internal/olm/operator/operator.go +++ b/internal/olm/operator/operator.go @@ -28,7 +28,7 @@ import ( // and injecting proxy container const ( - DefaultTimeout = time.Minute * 2 + defaultTimeout = time.Minute * 2 ) // OLMCmd configures deployment and teardown of an operator via an OLM @@ -91,7 +91,7 @@ func (c *OLMCmd) AddToFlagSet(fs *pflag.FlagSet) { fs.StringVar(&c.KubeconfigPath, "kubeconfig", "", "Path to kubeconfig") fs.StringVar(&c.OperatorNamespace, "namespace", "", "Namespace in which to create resources") fs.StringSliceVar(&c.IncludePaths, "include", nil, "Path to Kubernetes resource manifests, ex. Role, Subscription. These supplement or override defaults generated by up/down") - fs.DurationVar(&c.Timeout, "timeout", DefaultTimeout, "Time to wait for the command to complete before failing") + fs.DurationVar(&c.Timeout, "timeout", defaultTimeout, "Time to wait for the command to complete before failing") fs.BoolVar(&c.Force, "force", false, "Force operator-sdk up/down to overwrite/delete all resources known to the command, respectively") } @@ -113,7 +113,7 @@ func (c *OLMCmd) validate() error { func (c *OLMCmd) initialize() { c.once.Do(func() { if c.Timeout <= 0 { - c.Timeout = DefaultTimeout + c.Timeout = defaultTimeout } }) } diff --git a/test/integration/test_suite.go b/test/integration/test_suite.go index 3119398251a..c95cc02fee8 100644 --- a/test/integration/test_suite.go +++ b/test/integration/test_suite.go @@ -21,7 +21,6 @@ import ( "os" "path/filepath" "strings" - "time" "github.com/ghodss/yaml" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" @@ -31,8 +30,8 @@ import ( ) const ( - defaultTimeout = 2 * time.Minute - defaultTestImageTag = "quay.io/example/test:latest" + // TODO(estroz): don't rely on prior tests building this (works in CI). + defaultTestImageTag = "quay.io/example/memcached-operator:0.0.1" ) var ( From bc43140e198328d56fa800c3f48a09bdf250aa01 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 17 Sep 2019 20:51:58 -0700 Subject: [PATCH 11/32] fix test image --- test/integration/operator_olm_test.go | 37 +++++++++++++++++++-------- test/integration/test_suite.go | 22 +++++++--------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/test/integration/operator_olm_test.go b/test/integration/operator_olm_test.go index 5c4cc359a4f..c672c03684f 100644 --- a/test/integration/operator_olm_test.go +++ b/test/integration/operator_olm_test.go @@ -18,11 +18,21 @@ import ( "io/ioutil" "os" "testing" + "time" operator "github.com/operator-framework/operator-sdk/internal/olm/operator" + "github.com/operator-framework/operator-sdk/pkg/k8sutil" - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + opv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" +) + +const ( + defaultTimeout = 4 * time.Minute +) + +var ( + kubeconfigPath = os.Getenv(k8sutil.KubeConfigEnvVar) ) func TestOLMIntegration(t *testing.T) { @@ -43,34 +53,35 @@ func SingleOperator(t *testing.T) { Kind: "Memcached", Name: "memcacheds.cache.example.com", Group: "cache.example.com", - Versions: []v1beta1.CustomResourceDefinitionVersion{ + Versions: []apiextv1beta1.CustomResourceDefinitionVersion{ {Name: "v1alpha1", Storage: true, Served: true}, }, }, }, - InstallModes: []v1alpha1.InstallMode{ - {Type: v1alpha1.InstallModeTypeOwnNamespace, Supported: true}, - {Type: v1alpha1.InstallModeTypeSingleNamespace, Supported: true}, - {Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: false}, - {Type: v1alpha1.InstallModeTypeAllNamespaces, Supported: true}, + InstallModes: []opv1alpha1.InstallMode{ + {Type: opv1alpha1.InstallModeTypeOwnNamespace, Supported: true}, + {Type: opv1alpha1.InstallModeTypeSingleNamespace, Supported: true}, + {Type: opv1alpha1.InstallModeTypeMultiNamespace, Supported: false}, + {Type: opv1alpha1.InstallModeTypeAllNamespaces, Supported: true}, }, } tmp, err := ioutil.TempDir("", "sdk-integration.") if err != nil { t.Fatal(err) } - defer os.RemoveAll(tmp) defaultChannel := "alpha" operatorName := "memcached-operator" operatorVersion := "0.0.2" manifestsDir, err := writeOperatorManifests(tmp, operatorName, defaultChannel, csvConfig) if err != nil { + os.RemoveAll(tmp) t.Fatal(err) } opcmd := operator.OLMCmd{ ManifestsDir: manifestsDir, OperatorVersion: operatorVersion, - KubeconfigPath: KubeconfigPath, + KubeconfigPath: kubeconfigPath, + Timeout: defaultTimeout, } cases := []struct { description string @@ -86,7 +97,11 @@ func SingleOperator(t *testing.T) { {"Remove operator after removal", opcmd.Down, false, true}, {"Remove operator after removal with force", opcmd.Down, true, false}, } - + defer func() { + opcmd.Force = true + opcmd.Down() + os.RemoveAll(tmp) + }() for _, c := range cases { opcmd.Force = c.force err := c.op() diff --git a/test/integration/test_suite.go b/test/integration/test_suite.go index c95cc02fee8..8a00e5d41f6 100644 --- a/test/integration/test_suite.go +++ b/test/integration/test_suite.go @@ -23,26 +23,22 @@ import ( "strings" "github.com/ghodss/yaml" - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + opv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/operator-framework/operator-registry/pkg/registry" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( // TODO(estroz): don't rely on prior tests building this (works in CI). - defaultTestImageTag = "quay.io/example/memcached-operator:0.0.1" -) - -var ( - KubeconfigPath = os.Getenv("KUBECONFIG") + defaultTestImageTag = "quay.io/example/memcached-operator:v0.0.1" ) type DefinitionKey struct { Kind string Name string Group string - Versions []v1beta1.CustomResourceDefinitionVersion + Versions []apiextv1beta1.CustomResourceDefinitionVersion } type CSVTemplateConfig struct { @@ -52,7 +48,7 @@ type CSVTemplateConfig struct { Maturity string ReplacesCSVName string CRDKeys []DefinitionKey - InstallModes []v1alpha1.InstallMode + InstallModes []opv1alpha1.InstallMode } const csvTmpl = `apiVersion: operators.coreos.com/v1alpha1 @@ -214,14 +210,14 @@ func writeOperatorManifests(root, operatorName, defaultChannel string, csvConfig }) bundleDir := filepath.Join(manifestsDir, csvConfig.OperatorVersion) for _, key := range csvConfig.CRDKeys { - crd := v1beta1.CustomResourceDefinition{ + crd := apiextv1beta1.CustomResourceDefinition{ TypeMeta: v1.TypeMeta{ - APIVersion: v1beta1.SchemeGroupVersion.String(), + APIVersion: apiextv1beta1.SchemeGroupVersion.String(), Kind: "CustomResourceDefinition", }, ObjectMeta: v1.ObjectMeta{Name: key.Name}, - Spec: v1beta1.CustomResourceDefinitionSpec{ - Names: v1beta1.CustomResourceDefinitionNames{ + Spec: apiextv1beta1.CustomResourceDefinitionSpec{ + Names: apiextv1beta1.CustomResourceDefinitionNames{ Kind: key.Kind, ListKind: key.Kind + "List", Singular: strings.ToLower(key.Kind), From 4e11d1d28fbab1febafc8cbd319692af7bc2269c Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 17 Sep 2019 22:26:23 -0700 Subject: [PATCH 12/32] prow CI integration tests and Makefile target --- Makefile | 4 ++++ hack/tests/alpha-olm-subcommands.sh | 17 ++--------------- hack/tests/integration.sh | 13 +++++++++++++ test/integration/operator_olm_test.go | 3 +++ test/integration/test_suite.go | 8 ++++++-- 5 files changed, 28 insertions(+), 17 deletions(-) create mode 100755 hack/tests/integration.sh diff --git a/Makefile b/Makefile index dfbe9a6b73b..772ce2cb395 100644 --- a/Makefile +++ b/Makefile @@ -125,6 +125,10 @@ test/subcommand/scorecard2: test/subcommand/alpha-olm: ./hack/tests/alpha-olm-subcommands.sh +.PHONY: test/integration +test/integration: + ./hack/tests/integration.sh + test/e2e: test/e2e/go test/e2e/ansible test/e2e/ansible-molecule test/e2e/helm test/e2e/go: diff --git a/hack/tests/alpha-olm-subcommands.sh b/hack/tests/alpha-olm-subcommands.sh index c8444d35738..ac951d44434 100755 --- a/hack/tests/alpha-olm-subcommands.sh +++ b/hack/tests/alpha-olm-subcommands.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash -source hack/lib/test_lib.sh +set -ex + test_version() { local version="$1" @@ -35,19 +36,5 @@ test_version() { echo $commandoutput | grep -F "Successfully uninstalled OLM" } -set -ex - -# olm install/uninstall test_version "latest" test_version "0.10.1" - -# olm up/down -if ! operator-sdk alpha olm install; then - echo "Failed to install OLM latest before 'olm up/down' test" - exit 1 -fi -go test -v ./test/integration/... -if ! operator-sdk alpha olm uninstall; then - echo "Failed to uninstall OLM latest after 'olm up/down' test" - exit 1 -fi diff --git a/hack/tests/integration.sh b/hack/tests/integration.sh new file mode 100755 index 00000000000..c1412e5f07f --- /dev/null +++ b/hack/tests/integration.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -eux + +# Prow CI setup. +component="memcached-operator" +eval IMAGE=$IMAGE_FORMAT +export OSDK_INTEGRATION_IMAGE="$IMAGE" + +# Integration tests will use default loading rules for the kubeconfig if +# KUBECONFIG is not set. +# Assumes OLM is installed. +go test -v ./test/integration diff --git a/test/integration/operator_olm_test.go b/test/integration/operator_olm_test.go index c672c03684f..4c043c67b7a 100644 --- a/test/integration/operator_olm_test.go +++ b/test/integration/operator_olm_test.go @@ -36,6 +36,9 @@ var ( ) func TestOLMIntegration(t *testing.T) { + if image, ok := os.LookupEnv(imageEnvVar); ok && image != "" { + defaultTestImageTag = image + } t.Run("Operator", func(t *testing.T) { t.Run("Single", SingleOperator) }) diff --git a/test/integration/test_suite.go b/test/integration/test_suite.go index 8a00e5d41f6..83ac405c6b0 100644 --- a/test/integration/test_suite.go +++ b/test/integration/test_suite.go @@ -30,8 +30,12 @@ import ( ) const ( - // TODO(estroz): don't rely on prior tests building this (works in CI). - defaultTestImageTag = "quay.io/example/memcached-operator:v0.0.1" + imageEnvVar = "OSDK_INTEGRATION_IMAGE" +) + +var ( + // Set with OSDK_INTEGRATION_IMAGE in CI. + defaultTestImageTag = "memcached-operator" ) type DefinitionKey struct { From 5ef27093a0e0c8fb4721f1440414e77de4432602 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 17 Sep 2019 22:38:56 -0700 Subject: [PATCH 13/32] redo CLI --- cmd/operator-sdk/alpha/cmd.go | 8 +---- cmd/operator-sdk/alpha/down/cmd.go | 30 ------------------- cmd/operator-sdk/alpha/olm/cmd.go | 4 ++- .../alpha/{down/olm/cmd.go => olm/down.go} | 6 ++-- .../alpha/{up/olm/cmd.go => olm/up.go} | 6 ++-- cmd/operator-sdk/alpha/up/cmd.go | 30 ------------------- 6 files changed, 10 insertions(+), 74 deletions(-) delete mode 100644 cmd/operator-sdk/alpha/down/cmd.go rename cmd/operator-sdk/alpha/{down/olm/cmd.go => olm/down.go} (90%) rename cmd/operator-sdk/alpha/{up/olm/cmd.go => olm/up.go} (90%) delete mode 100644 cmd/operator-sdk/alpha/up/cmd.go diff --git a/cmd/operator-sdk/alpha/cmd.go b/cmd/operator-sdk/alpha/cmd.go index 78226041933..de389a4f042 100644 --- a/cmd/operator-sdk/alpha/cmd.go +++ b/cmd/operator-sdk/alpha/cmd.go @@ -15,9 +15,7 @@ package alpha import ( - "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/down" "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/olm" - "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/up" "github.com/spf13/cobra" ) @@ -28,10 +26,6 @@ func NewCmd() *cobra.Command { Short: "Run an alpha subcommand", } - cmd.AddCommand( - olm.NewCmd(), - up.NewCmd(), - down.NewCmd(), - ) + cmd.AddCommand(olm.NewCmd()) return cmd } diff --git a/cmd/operator-sdk/alpha/down/cmd.go b/cmd/operator-sdk/alpha/down/cmd.go deleted file mode 100644 index 2b786e1579c..00000000000 --- a/cmd/operator-sdk/alpha/down/cmd.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019 The Operator-SDK Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package down - -import ( - downolm "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/down/olm" - - "github.com/spf13/cobra" -) - -func NewCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "down", - Short: "Tear down your operator in a Kubernetes cluster", - } - cmd.AddCommand(downolm.NewOLMCmd()) - return cmd -} diff --git a/cmd/operator-sdk/alpha/olm/cmd.go b/cmd/operator-sdk/alpha/olm/cmd.go index 13fb3c00f1f..03242337ade 100644 --- a/cmd/operator-sdk/alpha/olm/cmd.go +++ b/cmd/operator-sdk/alpha/olm/cmd.go @@ -21,12 +21,14 @@ import ( func NewCmd() *cobra.Command { cmd := &cobra.Command{ Use: "olm", - Short: "Manage the Operator Lifecycle Manager installation in your cluster", + Short: "Manage the Operator Lifecycle Manager installation and Operators in your cluster", } cmd.AddCommand( NewInstallCmd(), NewUninstallCmd(), NewStatusCmd(), + NewUpCmd(), + NewDownCmd(), ) return cmd } diff --git a/cmd/operator-sdk/alpha/down/olm/cmd.go b/cmd/operator-sdk/alpha/olm/down.go similarity index 90% rename from cmd/operator-sdk/alpha/down/olm/cmd.go rename to cmd/operator-sdk/alpha/olm/down.go index 42e054faccf..488098ae77a 100644 --- a/cmd/operator-sdk/alpha/down/olm/cmd.go +++ b/cmd/operator-sdk/alpha/olm/down.go @@ -23,11 +23,11 @@ import ( "github.com/spf13/cobra" ) -func NewOLMCmd() *cobra.Command { +func NewDownCmd() *cobra.Command { c := &olmoperator.OLMCmd{} cmd := &cobra.Command{ - Use: "olm", - Short: "Tear down your operator with the Operator Lifecycle Manager", + Use: "down", + Short: "Tear down your operator with Operator Lifecycle Manager", RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("command %q requires exactly one argument", cmd.CommandPath()) diff --git a/cmd/operator-sdk/alpha/up/olm/cmd.go b/cmd/operator-sdk/alpha/olm/up.go similarity index 90% rename from cmd/operator-sdk/alpha/up/olm/cmd.go rename to cmd/operator-sdk/alpha/olm/up.go index 15d0f6335f1..d880abdeaa8 100644 --- a/cmd/operator-sdk/alpha/up/olm/cmd.go +++ b/cmd/operator-sdk/alpha/olm/up.go @@ -23,11 +23,11 @@ import ( "github.com/spf13/cobra" ) -func NewOLMCmd() *cobra.Command { +func NewUpCmd() *cobra.Command { c := &olmoperator.OLMCmd{} cmd := &cobra.Command{ - Use: "olm", - Short: "Deploy your operator with the Operator Lifecycle Manager", + Use: "up", + Short: "Deploy your operator with Operator Lifecycle Manager", RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("command %q requires exactly one argument", cmd.CommandPath()) diff --git a/cmd/operator-sdk/alpha/up/cmd.go b/cmd/operator-sdk/alpha/up/cmd.go deleted file mode 100644 index c20d1c1c7de..00000000000 --- a/cmd/operator-sdk/alpha/up/cmd.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019 The Operator-SDK Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package up - -import ( - upolm "github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/up/olm" - - "github.com/spf13/cobra" -) - -func NewCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "up", - Short: "Deploy your operator to a Kubernetes cluster", - } - cmd.AddCommand(upolm.NewOLMCmd()) - return cmd -} From cf7e499c657f4d7b4ffdf87ebf78c8ec8f31188b Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 17 Sep 2019 22:46:51 -0700 Subject: [PATCH 14/32] remove unused variable --- internal/olm/operator/internal/configmap.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index 86f0931d410..2c022bcfe8a 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -110,8 +110,6 @@ const ( // The directory containing all manifests for an operator, with the // package manifest being top-level. containerManifestsDir = "/registry/manifests" - // The directory containing a flat set of all files from all bundles. - containerOperatorDir = containerManifestsDir + "/operator" ) func getRegistryConfigMapName(pkgName string) string { From 320bec70d24d87f7f5106032e90bc498e6f21b5a Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 17 Sep 2019 22:53:24 -0700 Subject: [PATCH 15/32] move FormatOperatorNameDNS1123 from util/{operator-registry -> k8sutil} --- internal/olm/operator/internal/configmap.go | 4 ++-- internal/olm/operator/internal/deployment.go | 6 +++--- internal/olm/operator/olm.go | 6 +++--- internal/util/k8sutil/k8sutil.go | 14 ++++++++++++++ internal/util/operator-registry/validate.go | 14 -------------- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index 2c022bcfe8a..8e696d2a7fb 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -21,7 +21,7 @@ import ( "fmt" "strings" - registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + "github.com/operator-framework/operator-sdk/internal/util/k8sutil" "github.com/ghodss/yaml" "github.com/operator-framework/operator-registry/pkg/registry" @@ -113,7 +113,7 @@ const ( ) func getRegistryConfigMapName(pkgName string) string { - name := registryutil.FormatOperatorNameDNS1123(pkgName) + name := k8sutil.FormatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-registry-bundles", name) } diff --git a/internal/olm/operator/internal/deployment.go b/internal/olm/operator/internal/deployment.go index 98038b6d7c9..00874abb6d1 100644 --- a/internal/olm/operator/internal/deployment.go +++ b/internal/olm/operator/internal/deployment.go @@ -17,7 +17,7 @@ package olm import ( "fmt" - registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + "github.com/operator-framework/operator-sdk/internal/util/k8sutil" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -34,12 +34,12 @@ const ( ) func getRegistryServerName(pkgName string) string { - name := registryutil.FormatOperatorNameDNS1123(pkgName) + name := k8sutil.FormatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-registry-server", name) } func getRegistryVolumeName(pkgName string) string { - name := registryutil.FormatOperatorNameDNS1123(pkgName) + name := k8sutil.FormatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-bundle-db", name) } diff --git a/internal/olm/operator/olm.go b/internal/olm/operator/olm.go index 8c5455c5177..76dc992a500 100644 --- a/internal/olm/operator/olm.go +++ b/internal/olm/operator/olm.go @@ -17,7 +17,7 @@ package olm import ( "fmt" - registryutil "github.com/operator-framework/operator-sdk/internal/util/operator-registry" + "github.com/operator-framework/operator-sdk/internal/util/k8sutil" olmapiv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" @@ -27,7 +27,7 @@ import ( ) func getSubscriptionName(csvName string) string { - name := registryutil.FormatOperatorNameDNS1123(csvName) + name := k8sutil.FormatOperatorNameDNS1123(csvName) return fmt.Sprintf("%s-sub", name) } @@ -86,7 +86,7 @@ func newSubscription(csvName, namespace string, opts ...func(*olmapiv1alpha1.Sub } func getCatalogSourceName(pkgName string) string { - name := registryutil.FormatOperatorNameDNS1123(pkgName) + name := k8sutil.FormatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-ocs", name) } diff --git a/internal/util/k8sutil/k8sutil.go b/internal/util/k8sutil/k8sutil.go index 28a1bcff34e..195382c2119 100644 --- a/internal/util/k8sutil/k8sutil.go +++ b/internal/util/k8sutil/k8sutil.go @@ -18,12 +18,14 @@ import ( "bytes" "fmt" "io" + "regexp" "strings" "unicode" "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -113,3 +115,15 @@ func GetTypeMetaFromBytes(b []byte) (t metav1.TypeMeta, err error) { Kind: u.GetKind(), }, nil } + +// dns1123LabelRegexp defines the character set allowed in a DNS 1123 label. +var dns1123LabelRegexp = regexp.MustCompile("[^a-zA-Z0-9]+") + +// FormatOperatorNameDNS1123 ensures name is DNS1123 label-compliant by +// replacing all non-compliant UTF-8 characters with "-". +func FormatOperatorNameDNS1123(name string) string { + if len(validation.IsDNS1123Label(name)) != 0 { + return dns1123LabelRegexp.ReplaceAllString(name, "-") + } + return name +} diff --git a/internal/util/operator-registry/validate.go b/internal/util/operator-registry/validate.go index 09859b90c36..a290dfcfff2 100644 --- a/internal/util/operator-registry/validate.go +++ b/internal/util/operator-registry/validate.go @@ -16,14 +16,12 @@ package registry import ( "fmt" - "regexp" olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/operator-framework/operator-registry/pkg/appregistry" "github.com/operator-framework/operator-registry/pkg/registry" "github.com/pkg/errors" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apimachinery/pkg/util/validation" ) // ValidatePackageManifest ensures each datum in pkg is valid relative to other @@ -59,18 +57,6 @@ func ValidatePackageManifest(pkg *registry.PackageManifest) error { return nil } -// dns1123LabelRegexp defines the character set allowed in a DNS 1123 label. -var dns1123LabelRegexp = regexp.MustCompile("[^a-zA-Z0-9]+") - -// FormatOperatorNameDNS1123 ensures name is DNS1123 label-compliant by -// replacing all non-compliant UTF-8 characters with "-". -func FormatOperatorNameDNS1123(name string) string { - if len(validation.IsDNS1123Label(name)) != 0 { - return dns1123LabelRegexp.ReplaceAllString(name, "-") - } - return name -} - // validateBundle ensures all objects in bundle have the correct data. // TODO(estroz): remove once operator-verify library is complete. func validateBundle(bundle *registry.Bundle) (err error) { From 9dce01483033790b0c7e70efcf804ea125aeb7dd Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Wed, 18 Sep 2019 11:38:49 -0700 Subject: [PATCH 16/32] some reorg --- internal/olm/operator/internal/deployment.go | 4 ++-- internal/olm/operator/operator.go | 4 ++-- internal/olm/operator/tenancy.go | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/olm/operator/internal/deployment.go b/internal/olm/operator/internal/deployment.go index 00874abb6d1..d92208c4362 100644 --- a/internal/olm/operator/internal/deployment.go +++ b/internal/olm/operator/internal/deployment.go @@ -112,8 +112,8 @@ const ( // getDBContainerCmd returns a command string that, when run, does two things: // 1. Runs a database initializer on the manifests in the current working -// directory. -// 2. Runs an operator-registry server serving the bundle database. +// directory. +// 2. Runs an operator-registry server serving the bundle database. // The database must be in the current working directory. func getDBContainerCmd(dbPath, logPath string) string { initCmd := fmt.Sprintf("/usr/bin/initializer -o %s", dbPath) diff --git a/internal/olm/operator/operator.go b/internal/olm/operator/operator.go index 3afc5ecd8cb..7b3a7eb2642 100644 --- a/internal/olm/operator/operator.go +++ b/internal/olm/operator/operator.go @@ -55,7 +55,7 @@ type OLMCmd struct { // InstallMode specifies which supported installMode should be used to // create an OperatorGroup. The format for this field is as follows: // - // "InstallModeType=ns1{,ns2{, ...}}" + // "InstallModeType=[ns1,ns2[, ...]]" // // The InstallModeType string passed must be marked as "supported" in the // CSV being installed. The namespaces passed must exist or be created by @@ -87,7 +87,7 @@ var installModeFormat = "InstallModeType=[ns1,ns2[, ...]]" func (c *OLMCmd) AddToFlagSet(fs *pflag.FlagSet) { fs.StringVar(&c.OperatorVersion, "operator-version", "", "Version of operator to deploy") - fs.StringVar(&c.InstallMode, "install-mode", "", "InstallMode to create OperatorGroup with."+fmt.Sprintf(" Format: %s", installModeFormat)) + fs.StringVar(&c.InstallMode, "install-mode", "", "InstallMode to create OperatorGroup with. Format: "+installModeFormat) fs.StringVar(&c.KubeconfigPath, "kubeconfig", "", "Path to kubeconfig") fs.StringVar(&c.OperatorNamespace, "namespace", "", "Namespace in which to create resources") fs.StringSliceVar(&c.IncludePaths, "include", nil, "Path to Kubernetes resource manifests, ex. Role, Subscription. These supplement or override defaults generated by up/down") diff --git a/internal/olm/operator/tenancy.go b/internal/olm/operator/tenancy.go index 511361d9f7a..0e00da4f4d4 100644 --- a/internal/olm/operator/tenancy.go +++ b/internal/olm/operator/tenancy.go @@ -215,6 +215,14 @@ func (m operatorManager) installModeCompatible(installMode olmapiv1alpha1.Instal return nil } +// Mapping of installMode string values to types, for validation. +var installModeStrings = map[string]olmapiv1alpha1.InstallModeType{ + string(olmapiv1alpha1.InstallModeTypeOwnNamespace): olmapiv1alpha1.InstallModeTypeOwnNamespace, + string(olmapiv1alpha1.InstallModeTypeSingleNamespace): olmapiv1alpha1.InstallModeTypeSingleNamespace, + string(olmapiv1alpha1.InstallModeTypeMultiNamespace): olmapiv1alpha1.InstallModeTypeMultiNamespace, + string(olmapiv1alpha1.InstallModeTypeAllNamespaces): olmapiv1alpha1.InstallModeTypeAllNamespaces, +} + // parseInstallModeKV parses an installMode string of the format // installModeFormat. func parseInstallModeKV(raw string) (olmapiv1alpha1.InstallModeType, []string, error) { @@ -234,14 +242,6 @@ func parseInstallModeKV(raw string) (olmapiv1alpha1.InstallModeType, []string, e return mode, namespaces, nil } -// Mapping of installMode string values to types, for validation. -var installModeStrings = map[string]olmapiv1alpha1.InstallModeType{ - string(olmapiv1alpha1.InstallModeTypeOwnNamespace): olmapiv1alpha1.InstallModeTypeOwnNamespace, - string(olmapiv1alpha1.InstallModeTypeSingleNamespace): olmapiv1alpha1.InstallModeTypeSingleNamespace, - string(olmapiv1alpha1.InstallModeTypeMultiNamespace): olmapiv1alpha1.InstallModeTypeMultiNamespace, - string(olmapiv1alpha1.InstallModeTypeAllNamespaces): olmapiv1alpha1.InstallModeTypeAllNamespaces, -} - // validateInstallModeWithNamespaces ensures namespaces are valid given mode. func validateInstallModeWithNamespaces(mode olmapiv1alpha1.InstallModeType, namespaces []string) error { switch mode { From 52931a227d4ff41d14589d0276252362dfffd7c6 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Thu, 26 Sep 2019 10:31:36 -0700 Subject: [PATCH 17/32] fix defaultChannel validation --- internal/util/operator-registry/validate.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/util/operator-registry/validate.go b/internal/util/operator-registry/validate.go index a290dfcfff2..dea5e4523c4 100644 --- a/internal/util/operator-registry/validate.go +++ b/internal/util/operator-registry/validate.go @@ -30,11 +30,12 @@ func ValidatePackageManifest(pkg *registry.PackageManifest) error { if pkg.PackageName == "" { return errors.New("package name cannot be empty") } - if len(pkg.Channels) == 0 { + numChannels := len(pkg.Channels) + if numChannels == 0 { return errors.New("channels cannot be empty") } - if pkg.DefaultChannelName == "" { - return errors.New("default channel cannot be empty") + if pkg.DefaultChannelName == "" && numChannels > 1 { + return errors.New("default channel cannot be empty if more than one channel exists") } seen := map[string]struct{}{} @@ -50,7 +51,7 @@ func ValidatePackageManifest(pkg *registry.PackageManifest) error { } seen[c.Name] = struct{}{} } - if _, ok := seen[pkg.DefaultChannelName]; !ok { + if _, found := seen[pkg.DefaultChannelName]; pkg.DefaultChannelName != "" && !found { return fmt.Errorf("default channel %q does not exist in channels", pkg.DefaultChannelName) } From d82f7dac4eb5e72ad87997ca0530a1d44849cc78 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 25 Oct 2019 12:10:19 -0700 Subject: [PATCH 18/32] WIP: testing e2e and prow integration --- ci/prow.Makefile | 3 +++ ci/tests/integration.sh | 13 +++++++++++++ hack/tests/integration.sh | 27 ++++++++++++++++++++++----- test/integration/operator_olm_test.go | 2 +- test/test-framework/build/Dockerfile | 14 ++++++++++++++ 5 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 ci/tests/integration.sh create mode 100644 test/test-framework/build/Dockerfile diff --git a/ci/prow.Makefile b/ci/prow.Makefile index 7e5ec5eef52..83ce5e16805 100644 --- a/ci/prow.Makefile +++ b/ci/prow.Makefile @@ -18,3 +18,6 @@ test-e2e-helm test/e2e/helm: test-subcommand test/subcommand: ./ci/tests/subcommand.sh + +test-integration: + ./ci/tests/integration.sh diff --git a/ci/tests/integration.sh b/ci/tests/integration.sh new file mode 100644 index 00000000000..c1412e5f07f --- /dev/null +++ b/ci/tests/integration.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -eux + +# Prow CI setup. +component="memcached-operator" +eval IMAGE=$IMAGE_FORMAT +export OSDK_INTEGRATION_IMAGE="$IMAGE" + +# Integration tests will use default loading rules for the kubeconfig if +# KUBECONFIG is not set. +# Assumes OLM is installed. +go test -v ./test/integration diff --git a/hack/tests/integration.sh b/hack/tests/integration.sh index c1412e5f07f..4be81e1bf69 100755 --- a/hack/tests/integration.sh +++ b/hack/tests/integration.sh @@ -2,12 +2,29 @@ set -eux -# Prow CI setup. -component="memcached-operator" -eval IMAGE=$IMAGE_FORMAT -export OSDK_INTEGRATION_IMAGE="$IMAGE" +source hack/lib/image_lib.sh + +export OSDK_INTEGRATION_IMAGE="quay.io/example/memcached-operator:v0.0.1" + +# Build the operator image. +pushd test/test-framework +operator-sdk build "$OSDK_INTEGRATION_IMAGE" +# If using a kind cluster, load the image into all nodes. +load_image_if_kind "$OSDK_INTEGRATION_IMAGE" +popd + +# Install OLM on the cluster if not installed. +is_installed=0 +if ! operator-sdk alpha olm status > /dev/null 2>&1; then + operator-sdk alpha olm install + is_installed=1 +fi # Integration tests will use default loading rules for the kubeconfig if # KUBECONFIG is not set. -# Assumes OLM is installed. go test -v ./test/integration + +# Uninstall OLM if it was installed for test purposes. +if eval "(( $is_installed ))"; then + operator-sdk alpha olm uninstall +fi diff --git a/test/integration/operator_olm_test.go b/test/integration/operator_olm_test.go index 4c043c67b7a..4c0ef17cad6 100644 --- a/test/integration/operator_olm_test.go +++ b/test/integration/operator_olm_test.go @@ -28,7 +28,7 @@ import ( ) const ( - defaultTimeout = 4 * time.Minute + defaultTimeout = 2 * time.Minute ) var ( diff --git a/test/test-framework/build/Dockerfile b/test/test-framework/build/Dockerfile new file mode 100644 index 00000000000..2bfd5317cbb --- /dev/null +++ b/test/test-framework/build/Dockerfile @@ -0,0 +1,14 @@ +FROM registry.access.redhat.com/ubi7/ubi-minimal:latest + +ENV OPERATOR=/usr/local/bin/memcached-operator \ + USER_UID=1001 \ + USER_NAME=memcached-operator + +COPY build/_output/bin/test-framework ${OPERATOR} + +COPY build/bin /usr/local/bin +RUN /usr/local/bin/user_setup + +ENTRYPOINT ["/usr/local/bin/entrypoint"] + +USER ${USER_UID} From 1e5154329a76fc62d35852fc6df8709f30f4a33d Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 8 Nov 2019 13:30:42 -0800 Subject: [PATCH 19/32] add integration tests to .travis.yml --- .travis.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 98dab903053..0390ef7dc45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -129,11 +129,13 @@ jobs: name: Subcommands on Kubernetes script: make test-subcommand - # Test olm install/uninstall subcommands on master, as these cannot be tested in prow/api-ci. + # Test olm subcommands on master. - if: tag IS NOT present AND branch = master <<: *test - name: OLM Install/Uninstall on Kubernetes - script: make test-subcommand-olm-install + name: OLM Integration on Kubernetes + script: + - make test-subcommand-olm-install + - make test-integration # Build and test ansible using molecule, as this cannot be tested in prow/api-ci. - if: tag IS NOT present AND branch = master From 1c600c31b3566679d59ced95fdb58bf4351f9db5 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 8 Nov 2019 13:38:56 -0800 Subject: [PATCH 20/32] fix unit tests and add CLI docs --- doc/cli/operator-sdk_alpha.md | 2 +- doc/cli/operator-sdk_alpha_olm.md | 6 ++-- doc/cli/operator-sdk_alpha_olm_down.md | 29 +++++++++++++++++++ doc/cli/operator-sdk_alpha_olm_install.md | 2 +- doc/cli/operator-sdk_alpha_olm_status.md | 2 +- doc/cli/operator-sdk_alpha_olm_uninstall.md | 2 +- doc/cli/operator-sdk_alpha_olm_up.md | 29 +++++++++++++++++++ .../util/operator-registry/validate_test.go | 8 ++--- 8 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 doc/cli/operator-sdk_alpha_olm_down.md create mode 100644 doc/cli/operator-sdk_alpha_olm_up.md diff --git a/doc/cli/operator-sdk_alpha.md b/doc/cli/operator-sdk_alpha.md index cf209d2b328..dd06e3ee093 100644 --- a/doc/cli/operator-sdk_alpha.md +++ b/doc/cli/operator-sdk_alpha.md @@ -15,5 +15,5 @@ Run an alpha subcommand ### SEE ALSO * [operator-sdk](operator-sdk.md) - An SDK for building operators with ease -* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation in your cluster +* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation and Operators in your cluster diff --git a/doc/cli/operator-sdk_alpha_olm.md b/doc/cli/operator-sdk_alpha_olm.md index f65d097ae95..2c0a94194ea 100644 --- a/doc/cli/operator-sdk_alpha_olm.md +++ b/doc/cli/operator-sdk_alpha_olm.md @@ -1,10 +1,10 @@ ## operator-sdk alpha olm -Manage the Operator Lifecycle Manager installation in your cluster +Manage the Operator Lifecycle Manager installation and Operators in your cluster ### Synopsis -Manage the Operator Lifecycle Manager installation in your cluster +Manage the Operator Lifecycle Manager installation and Operators in your cluster ### Options @@ -15,7 +15,9 @@ Manage the Operator Lifecycle Manager installation in your cluster ### SEE ALSO * [operator-sdk alpha](operator-sdk_alpha.md) - Run an alpha subcommand +* [operator-sdk alpha olm down](operator-sdk_alpha_olm_down.md) - Tear down your operator with Operator Lifecycle Manager * [operator-sdk alpha olm install](operator-sdk_alpha_olm_install.md) - Install Operator Lifecycle Manager in your cluster * [operator-sdk alpha olm status](operator-sdk_alpha_olm_status.md) - Get the status of the Operator Lifecycle Manager installation in your cluster * [operator-sdk alpha olm uninstall](operator-sdk_alpha_olm_uninstall.md) - Uninstall Operator Lifecycle Manager from your cluster +* [operator-sdk alpha olm up](operator-sdk_alpha_olm_up.md) - Deploy your operator with Operator Lifecycle Manager diff --git a/doc/cli/operator-sdk_alpha_olm_down.md b/doc/cli/operator-sdk_alpha_olm_down.md new file mode 100644 index 00000000000..cbbb9e9f802 --- /dev/null +++ b/doc/cli/operator-sdk_alpha_olm_down.md @@ -0,0 +1,29 @@ +## operator-sdk alpha olm down + +Tear down your operator with Operator Lifecycle Manager + +### Synopsis + +Tear down your operator with Operator Lifecycle Manager + +``` +operator-sdk alpha olm down [flags] +``` + +### Options + +``` + --force Force operator-sdk up/down to overwrite/delete all resources known to the command, respectively + -h, --help help for down + --include strings Path to Kubernetes resource manifests, ex. Role, Subscription. These supplement or override defaults generated by up/down + --install-mode string InstallMode to create OperatorGroup with. Format: InstallModeType=[ns1,ns2[, ...]] + --kubeconfig string Path to kubeconfig + --namespace string Namespace in which to create resources + --operator-version string Version of operator to deploy + --timeout duration Time to wait for the command to complete before failing (default 2m0s) +``` + +### SEE ALSO + +* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation and Operators in your cluster + diff --git a/doc/cli/operator-sdk_alpha_olm_install.md b/doc/cli/operator-sdk_alpha_olm_install.md index aa62474d40f..a4cc724c7f6 100644 --- a/doc/cli/operator-sdk_alpha_olm_install.md +++ b/doc/cli/operator-sdk_alpha_olm_install.md @@ -20,5 +20,5 @@ operator-sdk alpha olm install [flags] ### SEE ALSO -* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation in your cluster +* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation and Operators in your cluster diff --git a/doc/cli/operator-sdk_alpha_olm_status.md b/doc/cli/operator-sdk_alpha_olm_status.md index 52bc68703b7..adba608b346 100644 --- a/doc/cli/operator-sdk_alpha_olm_status.md +++ b/doc/cli/operator-sdk_alpha_olm_status.md @@ -19,5 +19,5 @@ operator-sdk alpha olm status [flags] ### SEE ALSO -* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation in your cluster +* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation and Operators in your cluster diff --git a/doc/cli/operator-sdk_alpha_olm_uninstall.md b/doc/cli/operator-sdk_alpha_olm_uninstall.md index b74539dd087..31d32d271c0 100644 --- a/doc/cli/operator-sdk_alpha_olm_uninstall.md +++ b/doc/cli/operator-sdk_alpha_olm_uninstall.md @@ -19,5 +19,5 @@ operator-sdk alpha olm uninstall [flags] ### SEE ALSO -* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation in your cluster +* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation and Operators in your cluster diff --git a/doc/cli/operator-sdk_alpha_olm_up.md b/doc/cli/operator-sdk_alpha_olm_up.md new file mode 100644 index 00000000000..bba2629ab42 --- /dev/null +++ b/doc/cli/operator-sdk_alpha_olm_up.md @@ -0,0 +1,29 @@ +## operator-sdk alpha olm up + +Deploy your operator with Operator Lifecycle Manager + +### Synopsis + +Deploy your operator with Operator Lifecycle Manager + +``` +operator-sdk alpha olm up [flags] +``` + +### Options + +``` + --force Force operator-sdk up/down to overwrite/delete all resources known to the command, respectively + -h, --help help for up + --include strings Path to Kubernetes resource manifests, ex. Role, Subscription. These supplement or override defaults generated by up/down + --install-mode string InstallMode to create OperatorGroup with. Format: InstallModeType=[ns1,ns2[, ...]] + --kubeconfig string Path to kubeconfig + --namespace string Namespace in which to create resources + --operator-version string Version of operator to deploy + --timeout duration Time to wait for the command to complete before failing (default 2m0s) +``` + +### SEE ALSO + +* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation and Operators in your cluster + diff --git a/internal/util/operator-registry/validate_test.go b/internal/util/operator-registry/validate_test.go index 5a84b967ac5..06a949acd4b 100644 --- a/internal/util/operator-registry/validate_test.go +++ b/internal/util/operator-registry/validate_test.go @@ -50,7 +50,7 @@ func TestValidatePackageManifest(t *testing.T) { }, { "no default channel and more than one channel", - true, "default channel cannot be empty", + true, "default channel cannot be empty if more than one channel exists", ®istry.PackageManifest{ Channels: []registry.PackageChannel{ {Name: "foo", CurrentCSVName: "bar"}, @@ -61,7 +61,7 @@ func TestValidatePackageManifest(t *testing.T) { }, { "default channel does not exist", - true, "default channel baz does not exist in channels", + true, "default channel \"baz\" does not exist in channels", ®istry.PackageManifest{ Channels: []registry.PackageChannel{ {Name: "foo", CurrentCSVName: "bar"}, @@ -81,7 +81,7 @@ func TestValidatePackageManifest(t *testing.T) { }, { "one channel's CSVName is empty", - true, "channel foo currentCSV cannot be empty", + true, "channel \"foo\" currentCSV cannot be empty", ®istry.PackageManifest{ Channels: []registry.PackageChannel{{Name: "foo"}}, DefaultChannelName: "baz", @@ -90,7 +90,7 @@ func TestValidatePackageManifest(t *testing.T) { }, { "duplicate channel name", - true, "duplicate package manifest channel name foo; channel names must be unique", + true, "duplicate package manifest channel name \"foo\"; channel names must be unique", ®istry.PackageManifest{ Channels: []registry.PackageChannel{ {Name: "foo", CurrentCSVName: "bar"}, From a5eb84fbc2a88ad7a07e56b7cd24ffe9ea35798c Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 8 Nov 2019 14:07:30 -0800 Subject: [PATCH 21/32] address PR comments --- cmd/operator-sdk/alpha/olm/down.go | 2 +- cmd/operator-sdk/alpha/olm/up.go | 2 +- internal/olm/operator/internal/configmap.go | 16 ++++++++-------- internal/olm/operator/internal/deployment.go | 13 +++++-------- internal/olm/operator/manager.go | 2 +- internal/olm/operator/olm.go | 6 +++--- internal/olm/operator/tenancy.go | 14 +++++++------- 7 files changed, 26 insertions(+), 29 deletions(-) diff --git a/cmd/operator-sdk/alpha/olm/down.go b/cmd/operator-sdk/alpha/olm/down.go index 488098ae77a..364fead6806 100644 --- a/cmd/operator-sdk/alpha/olm/down.go +++ b/cmd/operator-sdk/alpha/olm/down.go @@ -27,7 +27,7 @@ func NewDownCmd() *cobra.Command { c := &olmoperator.OLMCmd{} cmd := &cobra.Command{ Use: "down", - Short: "Tear down your operator with Operator Lifecycle Manager", + Short: "Tears down the operator with Operator Lifecycle Manager", RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("command %q requires exactly one argument", cmd.CommandPath()) diff --git a/cmd/operator-sdk/alpha/olm/up.go b/cmd/operator-sdk/alpha/olm/up.go index d880abdeaa8..4ea43de5112 100644 --- a/cmd/operator-sdk/alpha/olm/up.go +++ b/cmd/operator-sdk/alpha/olm/up.go @@ -27,7 +27,7 @@ func NewUpCmd() *cobra.Command { c := &olmoperator.OLMCmd{} cmd := &cobra.Command{ Use: "up", - Short: "Deploy your operator with Operator Lifecycle Manager", + Short: "Launches the operator with Operator Lifecycle Manager", RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("command %q requires exactly one argument", cmd.CommandPath()) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index 8e696d2a7fb..2cfe033608e 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -31,9 +31,15 @@ import ( "k8s.io/apimachinery/pkg/types" ) -// RegistryDataStale checks if manifest data stored in the registry is stale +const ( + // The directory containing all manifests for an operator, with the + // package manifest being top-level. + containerManifestsDir = "/registry/manifests" +) + +// IsManifestDataStale checks if manifest data stored in the registry is stale // by comparing it to manifest data currently managed by m. -func (m *RegistryResources) RegistryDataStale(ctx context.Context, namespace string) (bool, error) { +func (m *RegistryResources) IsManifestDataStale(ctx context.Context, namespace string) (bool, error) { pkg := m.Manifests.GetPackageManifest() pkgName := pkg.PackageName nn := types.NamespacedName{ @@ -106,12 +112,6 @@ func createConfigMapBinaryData(pkg registry.PackageManifest, bundles []*registry return binaryKeyValues, nil } -const ( - // The directory containing all manifests for an operator, with the - // package manifest being top-level. - containerManifestsDir = "/registry/manifests" -) - func getRegistryConfigMapName(pkgName string) string { name := k8sutil.FormatOperatorNameDNS1123(pkgName) return fmt.Sprintf("%s-registry-bundles", name) diff --git a/internal/olm/operator/internal/deployment.go b/internal/olm/operator/internal/deployment.go index d92208c4362..639e2ae0ed0 100644 --- a/internal/olm/operator/internal/deployment.go +++ b/internal/olm/operator/internal/deployment.go @@ -31,6 +31,11 @@ const ( registryBaseImage = "quay.io/openshift/origin-operator-registry:latest" // The port registry-server will listen on within a container. registryGRPCPort = 50051 + // Path of the bundle database generated by initializer. + regisryDBName = "bundle.db" + // Path of the log file generated by registry-server. + // TODO(estroz): have this log file in an obvious place, ex. /var/log. + registryLogFile = "termination.log" ) func getRegistryServerName(pkgName string) string { @@ -102,14 +107,6 @@ func withContainerVolumeMounts(volName string, paths []string) func(*appsv1.Depl } } -const ( - // Path of the bundle database generated by initializer. - regisryDBName = "bundle.db" - // Path of the log file generated by registry-server. - // TODO(estroz): have this log file in an obvious place, ex. /var/log. - registryLogFile = "termination.log" -) - // getDBContainerCmd returns a command string that, when run, does two things: // 1. Runs a database initializer on the manifests in the current working // directory. diff --git a/internal/olm/operator/manager.go b/internal/olm/operator/manager.go index 63d01e53adb..722759204a5 100644 --- a/internal/olm/operator/manager.go +++ b/internal/olm/operator/manager.go @@ -263,7 +263,7 @@ func (m operatorManager) registryUp(ctx context.Context, namespace string) error Client: m.client, Manifests: m.manifests, } - registryStale, err := rr.RegistryDataStale(ctx, namespace) + registryStale, err := rr.IsManifestDataStale(ctx, namespace) if err != nil { if !apierrors.IsNotFound(err) { return errors.Wrap(err, "error checking registry data") diff --git a/internal/olm/operator/olm.go b/internal/olm/operator/olm.go index 76dc992a500..4a9c0dbdcdc 100644 --- a/internal/olm/operator/olm.go +++ b/internal/olm/operator/olm.go @@ -26,6 +26,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// General OperatorGroup for operators created with the SDK. +const sdkOperatorGroupName = "operator-sdk-og" + func getSubscriptionName(csvName string) string { name := k8sutil.FormatOperatorNameDNS1123(csvName) return fmt.Sprintf("%s-sub", name) @@ -123,9 +126,6 @@ func newCatalogSource(pkgName, namespace string, opts ...func(*olmapiv1alpha1.Ca return cs } -// General OperatorGroup for operators created with the SDK. -const sdkOperatorGroupName = "operator-sdk-og" - // withGRPC returns a function that sets the OperatorGroup argument's // targetNamespaces to namespaces. namespaces can be length 0..N; if // namespaces length is 0, targetNamespaces is set to an empty string, diff --git a/internal/olm/operator/tenancy.go b/internal/olm/operator/tenancy.go index 0e00da4f4d4..4f0fb8f041f 100644 --- a/internal/olm/operator/tenancy.go +++ b/internal/olm/operator/tenancy.go @@ -35,6 +35,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +const ( + // Annotation containing a CSV's member OperatorGroup's name. + olmOperatorGroupAnnotation = "olm.operatorGroup" + // Annotation containing a CSV's member OperatorGroup's namespace. + olmOperatorGroupNamespaceAnnotation = "olm.operatorNamespace" +) + // operatorGroupDown handles logic to decide whether the SDK-managed // OperatorGroup can be created. // @@ -155,13 +162,6 @@ func (m *operatorManager) operatorGroupDown(ctx context.Context) error { return nil } -const ( - // Annotation containing a CSV's member OperatorGroup's name. - olmOperatorGroupAnnotation = "olm.operatorGroup" - // Annotation containing a CSV's member OperatorGroup's namespace. - olmOperatorGroupNamespaceAnnotation = "olm.operatorNamespace" -) - // getCSVsInOperatorGroup gets all CSVs that are members of the OperatorGroup // in namespace with name ogName. If ogCSVs is empty, no CSVs are members. func (m operatorManager) getCSVsInOperatorGroup(ctx context.Context, ogName, namespace string) (ogCSVs []*olmapiv1alpha1.ClusterServiceVersion, err error) { From 918a6a0d018694988fd2279b706de80b16b30486 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 8 Nov 2019 14:07:49 -0800 Subject: [PATCH 22/32] fix docs --- doc/cli/operator-sdk_alpha_olm.md | 4 ++-- doc/cli/operator-sdk_alpha_olm_down.md | 4 ++-- doc/cli/operator-sdk_alpha_olm_up.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/cli/operator-sdk_alpha_olm.md b/doc/cli/operator-sdk_alpha_olm.md index 2c0a94194ea..ae7e6cbe1f7 100644 --- a/doc/cli/operator-sdk_alpha_olm.md +++ b/doc/cli/operator-sdk_alpha_olm.md @@ -15,9 +15,9 @@ Manage the Operator Lifecycle Manager installation and Operators in your cluster ### SEE ALSO * [operator-sdk alpha](operator-sdk_alpha.md) - Run an alpha subcommand -* [operator-sdk alpha olm down](operator-sdk_alpha_olm_down.md) - Tear down your operator with Operator Lifecycle Manager +* [operator-sdk alpha olm down](operator-sdk_alpha_olm_down.md) - Tears down the operator with Operator Lifecycle Manager * [operator-sdk alpha olm install](operator-sdk_alpha_olm_install.md) - Install Operator Lifecycle Manager in your cluster * [operator-sdk alpha olm status](operator-sdk_alpha_olm_status.md) - Get the status of the Operator Lifecycle Manager installation in your cluster * [operator-sdk alpha olm uninstall](operator-sdk_alpha_olm_uninstall.md) - Uninstall Operator Lifecycle Manager from your cluster -* [operator-sdk alpha olm up](operator-sdk_alpha_olm_up.md) - Deploy your operator with Operator Lifecycle Manager +* [operator-sdk alpha olm up](operator-sdk_alpha_olm_up.md) - Launches the operator with Operator Lifecycle Manager diff --git a/doc/cli/operator-sdk_alpha_olm_down.md b/doc/cli/operator-sdk_alpha_olm_down.md index cbbb9e9f802..8cfb8e5405f 100644 --- a/doc/cli/operator-sdk_alpha_olm_down.md +++ b/doc/cli/operator-sdk_alpha_olm_down.md @@ -1,10 +1,10 @@ ## operator-sdk alpha olm down -Tear down your operator with Operator Lifecycle Manager +Tears down the operator with Operator Lifecycle Manager ### Synopsis -Tear down your operator with Operator Lifecycle Manager +Tears down the operator with Operator Lifecycle Manager ``` operator-sdk alpha olm down [flags] diff --git a/doc/cli/operator-sdk_alpha_olm_up.md b/doc/cli/operator-sdk_alpha_olm_up.md index bba2629ab42..9f6b7929b6a 100644 --- a/doc/cli/operator-sdk_alpha_olm_up.md +++ b/doc/cli/operator-sdk_alpha_olm_up.md @@ -1,10 +1,10 @@ ## operator-sdk alpha olm up -Deploy your operator with Operator Lifecycle Manager +Launches the operator with Operator Lifecycle Manager ### Synopsis -Deploy your operator with Operator Lifecycle Manager +Launches the operator with Operator Lifecycle Manager ``` operator-sdk alpha olm up [flags] From 3842b553985d3647371c399af66d8b26f3b12ad1 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Thu, 21 Nov 2019 15:48:51 -0800 Subject: [PATCH 23/32] go.sum: revendor --- go.sum | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/go.sum b/go.sum index 06e7829b1fc..575d7f9bbac 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,6 @@ bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c/go.mod h1:1vhO7Mn/FZMgOgDVGLy5X1mE6rq1HbkBdkF/yj8zkcg= +bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= 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= @@ -42,7 +43,6 @@ github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZC github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= @@ -179,7 +179,9 @@ github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs= github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f h1:AUj1VoZUfhPhOPHULCQQDnGhRelpFWHMLhQVWDsS0v4= github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= 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/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -349,6 +351,7 @@ github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190203031600-7a902570cb17 h1:prg2TTpTOcJF1jRWL2zSU1FQNgB0STAFNux8GK82y8k= @@ -356,8 +359,6 @@ github.com/gregjones/httpcache v0.0.0-20190203031600-7a902570cb17/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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= @@ -528,28 +529,24 @@ github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830/go.mod h github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= github.com/openshift/api v3.9.1-0.20190717200738-0390d1e77d64+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= -github.com/openshift/api v3.9.1-0.20190924102528-32369d4db2ad+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= github.com/openshift/client-go v0.0.0-20190627172412-c44a8b61b9f4/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= -github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII= github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/operator-framework/go-appr v0.0.0-20180917210448-f2aef88446f2/go.mod h1:YNzwUx1i6C4dXWcffyq3yaIb0rh/K8/OvQ4vG0SNlSw= github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190926160646-a61144936680 h1:7/79nDoXBQGFidupTJNeVJef3TeirnaxeFP5kNF+YLk= github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190926160646-a61144936680/go.mod h1:NSydXcV6IwxJ6gZwegvanaVCzYt9Ep6Cl1HFcd1Ithk= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20191115003340-16619cd27fa5 h1:rjaihxY50c5C+kbQIK4s36R8zxByATYrgRbua4eiG6o= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20191115003340-16619cd27fa5/go.mod h1:zL34MNy92LPutBH5gQK+gGhtgTUlZZX03I2G12vWHF4= github.com/operator-framework/operator-marketplace v0.0.0-20190216021216-57300a3ef3ba/go.mod h1:msZSL8pXwzQjB+hU+awVrZQw94IwJi3sNZVD3NoESIs= github.com/operator-framework/operator-registry v1.1.1/go.mod h1:7D4WEwL+EKti5npUh4/u64DQhawCBRugp8Ql20duUb4= -github.com/operator-framework/operator-registry v1.5.1 h1:8ruUOG6IBDVTAXYWKsv6hwr4yv/0SFPFPAYGCpcv97E= -github.com/operator-framework/operator-registry v1.5.1/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= github.com/operator-framework/operator-registry v1.5.3 h1:az83WDwgB+tHsmVn+tFq72yQBbaUAye8e4+KkDQmzLs= github.com/operator-framework/operator-registry v1.5.3/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= +github.com/otiai10/copy v1.0.1 h1:gtBjD8aq4nychvRZ2CyJvFWAw0aja+VHazDdruZKGZA= github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776 h1:o59bHXu8Ejas8Kq6pjoVJQ9/neN66SM8AKh6wI42BBs= github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= +github.com/otiai10/mint v1.2.4 h1:DxYL0itZyPaR5Z9HILdxSoHx+gNs6Yx+neOGS3IVUk0= github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -859,8 +856,6 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -961,7 +956,6 @@ k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51 h1:RBkTKVMF+xsNsSOVc0+HdC0B5gD k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51/go.mod h1:gL826ZTIfD4vXTGlmzgTbliCAT9NGiqpCqK2aNYv5MQ= k8s.io/kubelet v0.0.0-20191016114556-7841ed97f1b2/go.mod h1:SBvrtLbuePbJygVXGGCMtWKH07+qrN2dE1iMnteSG8E= k8s.io/kubernetes v1.11.8-beta.0.0.20190124204751-3a10094374f2/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/kubernetes v1.16.0/go.mod h1:nlP2zevWKRGKuaaVbKIwozU0Rjg9leVDXkL4YTtjmVs= k8s.io/kubernetes v1.16.2 h1:k0f/OVp6Yfv+UMTm6VYKhqjRgcvHh4QhN9coanjrito= k8s.io/kubernetes v1.16.2/go.mod h1:SmhGgKfQ30imqjFVj8AI+iW+zSyFsswNErKYeTfgoH0= k8s.io/legacy-cloud-providers v0.0.0-20191016115753-cf0698c3a16b/go.mod h1:tKW3pKqdRW8pMveUTpF5pJuCjQxg6a25iLo+Z9BXVH0= @@ -985,8 +979,6 @@ sigs.k8s.io/controller-tools v0.2.2/go.mod h1:8SNGuj163x/sMwydREj7ld5mIMJu1cDanI sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/structured-merge-diff v0.0.0-20190302045857-e85c7b244fd2/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -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-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM= sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= From 50ee6892eaee3ee987915aa0ad5ffd93553fca3c Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 22 Nov 2019 13:41:41 -0800 Subject: [PATCH 24/32] update comment and CRD scheme installation --- internal/olm/operator/internal/configmap.go | 3 ++- internal/olm/operator/manager.go | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index 2cfe033608e..d7fa4ff5bd0 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -56,7 +56,8 @@ func (m *RegistryResources) IsManifestDataStale(ctx context.Context, namespace s if err != nil { return false, errors.Wrap(err, "error creating binary data") } - // If lengths don't match we have added or removed a file. + // If the number of files to be added to the registry don't match the number + // of files currently in the registry, we have added or removed a file. if len(newData) != len(configmap.BinaryData) { return true, nil } diff --git a/internal/olm/operator/manager.go b/internal/olm/operator/manager.go index 722759204a5..66984dcac0e 100644 --- a/internal/olm/operator/manager.go +++ b/internal/olm/operator/manager.go @@ -29,7 +29,7 @@ import ( olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/pkg/errors" log "github.com/sirupsen/logrus" - apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + apiextinstall "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -46,9 +46,7 @@ var ( ) func init() { - if err := apiextv1beta1.AddToScheme(Scheme); err != nil { - log.Fatalf("Failed to add Kubhernetes API extensions v1beta1 types to scheme: %v", err) - } + apiextinstall.Install(Scheme) if err := olmapiv1.AddToScheme(Scheme); err != nil { log.Fatalf("Failed to add OLM operator API v1 types to scheme: %v", err) } From a97f01e57a06f3b37ae2e86dfce0374f35fd0737 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 22 Nov 2019 13:45:45 -0800 Subject: [PATCH 25/32] go.mod: bump OLM to 0.13.0 which uses kk8s 1.16 --- go.mod | 9 +-------- go.sum | 40 +++++++++++++++------------------------- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index 1f1e844e75c..1f2b6d8aaab 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/mapstructure v1.1.2 - github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190125151539-1e295784b30a + github.com/operator-framework/operator-lifecycle-manager v0.0.0-20191115003340-16619cd27fa5 // 0.13.0 github.com/operator-framework/operator-registry v1.5.3 github.com/pborman/uuid v1.2.0 github.com/pkg/errors v0.8.1 @@ -91,10 +91,3 @@ replace ( k8s.io/metrics => k8s.io/metrics v0.0.0-20191016113814-3b1a734dba6e k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.0.0-20191016112829-06bb3c9d77c9 ) - -replace ( - github.com/openshift/api => github.com/openshift/api v3.9.1-0.20190717200738-0390d1e77d64+incompatible - github.com/openshift/client-go => github.com/openshift/client-go v0.0.0-20190627172412-c44a8b61b9f4 - github.com/operator-framework/operator-lifecycle-manager => github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190926160646-a61144936680 - sigs.k8s.io/structured-merge-diff => sigs.k8s.io/structured-merge-diff v0.0.0-20190302045857-e85c7b244fd2 -) diff --git a/go.sum b/go.sum index 575d7f9bbac..0e2f3a4851b 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= -bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c/go.mod h1:1vhO7Mn/FZMgOgDVGLy5X1mE6rq1HbkBdkF/yj8zkcg= bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -43,6 +42,7 @@ github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZC github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= @@ -108,7 +108,6 @@ github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/coredns/corefile-migration v1.0.2/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= -github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -176,7 +175,6 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs= @@ -187,7 +185,6 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w= github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful-swagger12 v0.0.0-20170926063155-7524189396c6/go.mod h1:qr0VowGBT4CS4Q8vFF8BSeKz34PuqKGxs/L0IAQA9DQ= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -298,7 +295,6 @@ github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= 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/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= @@ -353,12 +349,13 @@ github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7 h1:6TSoaYExHper8PYsJu23GWVNOyYRCSnIFyxKgLSZ54w= github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/gregjones/httpcache v0.0.0-20190203031600-7a902570cb17 h1:prg2TTpTOcJF1jRWL2zSU1FQNgB0STAFNux8GK82y8k= -github.com/gregjones/httpcache v0.0.0-20190203031600-7a902570cb17/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-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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= @@ -528,16 +525,15 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= -github.com/openshift/api v3.9.1-0.20190717200738-0390d1e77d64+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= -github.com/openshift/client-go v0.0.0-20190627172412-c44a8b61b9f4/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= +github.com/openshift/api v3.9.1-0.20190924102528-32369d4db2ad+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII= github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/operator-framework/go-appr v0.0.0-20180917210448-f2aef88446f2/go.mod h1:YNzwUx1i6C4dXWcffyq3yaIb0rh/K8/OvQ4vG0SNlSw= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190926160646-a61144936680 h1:7/79nDoXBQGFidupTJNeVJef3TeirnaxeFP5kNF+YLk= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190926160646-a61144936680/go.mod h1:NSydXcV6IwxJ6gZwegvanaVCzYt9Ep6Cl1HFcd1Ithk= -github.com/operator-framework/operator-marketplace v0.0.0-20190216021216-57300a3ef3ba/go.mod h1:msZSL8pXwzQjB+hU+awVrZQw94IwJi3sNZVD3NoESIs= -github.com/operator-framework/operator-registry v1.1.1/go.mod h1:7D4WEwL+EKti5npUh4/u64DQhawCBRugp8Ql20duUb4= +github.com/operator-framework/operator-lifecycle-manager v0.0.0-20191115003340-16619cd27fa5 h1:rjaihxY50c5C+kbQIK4s36R8zxByATYrgRbua4eiG6o= +github.com/operator-framework/operator-lifecycle-manager v0.0.0-20191115003340-16619cd27fa5/go.mod h1:zL34MNy92LPutBH5gQK+gGhtgTUlZZX03I2G12vWHF4= +github.com/operator-framework/operator-registry v1.5.1/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= github.com/operator-framework/operator-registry v1.5.3 h1:az83WDwgB+tHsmVn+tFq72yQBbaUAye8e4+KkDQmzLs= github.com/operator-framework/operator-registry v1.5.3/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= github.com/otiai10/copy v1.0.1 h1:gtBjD8aq4nychvRZ2CyJvFWAw0aja+VHazDdruZKGZA= @@ -637,7 +633,6 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= 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= @@ -651,7 +646,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50/go.mod h1:1pdIZTAHUz+HDKDVZ++5xg/duPlhKAIzw9qy42CWYp4= github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -669,7 +663,6 @@ github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1C github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= @@ -756,7 +749,6 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL 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-20181105165119-ca4130e427c7/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= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -814,7 +806,6 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181207222222-4c874b978acb/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -856,6 +847,8 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -927,7 +920,6 @@ k8s.io/component-base v0.0.0-20191016111319-039242c015a9/go.mod h1:SuWowIgd/dtU/ k8s.io/cri-api v0.0.0-20190828162817-608eb1dad4ac/go.mod h1:BvtUaNBr0fEpzb11OfrQiJLsLPtqbmulpo1fPwcpP6Q= k8s.io/csi-translation-lib v0.0.0-20191016115521-756ffa5af0bd/go.mod h1:lf1VBseeLanBpSXD0N9tuPx1ylI8sA0j6f+rckCKiIk= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f h1:eW/6wVuHNZgQJmFesyAxu0cvj0WAHHUuGaLbPcmNY3Q= k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= @@ -943,7 +935,6 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/kube-aggregator v0.0.0-20191016112429-9587704a8ad4 h1:Tv+DHbQg2ozCJqmuw5poFX7sxs2mJPUm7MEz3sQEULM= k8s.io/kube-aggregator v0.0.0-20191016112429-9587704a8ad4/go.mod h1:+aW0UZgSXdTSHTIFnWnueEuXjOqerDUxGIw6Ygr+vYY= k8s.io/kube-controller-manager v0.0.0-20191016114939-2b2b218dc1df/go.mod h1:WgrTcPKYAfNa9C0LV1UeK+XqfbSOUH1WGq/vX5UiW40= -k8s.io/kube-openapi v0.0.0-20181031203759-72693cb1fadd/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190320154901-5e45bb682580/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d h1:Xpe6sK+RY4ZgCTyZ3y273UmFmURhjtoJiwOMbQsXitY= @@ -955,7 +946,7 @@ k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+ k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51 h1:RBkTKVMF+xsNsSOVc0+HdC0B5gD1sr6s6Cu5w9qNbuQ= k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51/go.mod h1:gL826ZTIfD4vXTGlmzgTbliCAT9NGiqpCqK2aNYv5MQ= k8s.io/kubelet v0.0.0-20191016114556-7841ed97f1b2/go.mod h1:SBvrtLbuePbJygVXGGCMtWKH07+qrN2dE1iMnteSG8E= -k8s.io/kubernetes v1.11.8-beta.0.0.20190124204751-3a10094374f2/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/kubernetes v1.16.0/go.mod h1:nlP2zevWKRGKuaaVbKIwozU0Rjg9leVDXkL4YTtjmVs= k8s.io/kubernetes v1.16.2 h1:k0f/OVp6Yfv+UMTm6VYKhqjRgcvHh4QhN9coanjrito= k8s.io/kubernetes v1.16.2/go.mod h1:SmhGgKfQ30imqjFVj8AI+iW+zSyFsswNErKYeTfgoH0= k8s.io/legacy-cloud-providers v0.0.0-20191016115753-cf0698c3a16b/go.mod h1:tKW3pKqdRW8pMveUTpF5pJuCjQxg6a25iLo+Z9BXVH0= @@ -963,7 +954,6 @@ k8s.io/metrics v0.0.0-20191016113814-3b1a734dba6e/go.mod h1:ve7/vMWeY5lEBkZf6Bt5 k8s.io/repo-infra v0.0.0-20181204233714-00fe14e3d1a3/go.mod h1:+G1xBfZDfVFsm1Tj/HNCvg4QqWx8rJ2Fxpqr1rqp/gQ= k8s.io/sample-apiserver v0.0.0-20191016112829-06bb3c9d77c9/go.mod h1:sXltHZrQa4jdKL14nOFRRUhhzpmbnRF0qGuAhRQbaxc= k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -k8s.io/utils v0.0.0-20190712204705-3dccf664f023/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= @@ -971,14 +961,14 @@ modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= -sigs.k8s.io/controller-runtime v0.1.10/go.mod h1:HFAYoOh6XMV+jKF1UjFwrknPbowfyHEHHRdJMf2jMX8= sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg= sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns= sigs.k8s.io/controller-tools v0.2.2 h1:tOXKme2gR7KoM6+7Y+nzjwjbXDgqLfTuX5r7+4dvlig= sigs.k8s.io/controller-tools v0.2.2/go.mod h1:8SNGuj163x/sMwydREj7ld5mIMJu1cDanIfnx6xsU70= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/structured-merge-diff v0.0.0-20190302045857-e85c7b244fd2/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +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-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM= sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= From c38257655aab3cfb26ff0cb1b356edbde61f317f Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Fri, 22 Nov 2019 14:31:55 -0800 Subject: [PATCH 26/32] update test/test-framework go.sum --- test/test-framework/go.sum | 85 +++++++++++--------------------------- 1 file changed, 24 insertions(+), 61 deletions(-) diff --git a/test/test-framework/go.sum b/test/test-framework/go.sum index c2599ec067c..38bbb427a34 100644 --- a/test/test-framework/go.sum +++ b/test/test-framework/go.sum @@ -1,5 +1,4 @@ bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= -bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c/go.mod h1:1vhO7Mn/FZMgOgDVGLy5X1mE6rq1HbkBdkF/yj8zkcg= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= @@ -36,6 +35,7 @@ github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF0 github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= @@ -95,10 +95,8 @@ github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/coredns/corefile-migration v1.0.2/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= -github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.9+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+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= @@ -106,8 +104,8 @@ github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHo 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-20181031085051-9002847aa142/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/prometheus-operator v0.34.0/go.mod h1:Li6rMllG/hYIyXfMuvUwhyC+hqwJVHdsDdP21hypT1M= @@ -135,7 +133,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/docker/distribution v2.6.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= @@ -153,17 +150,13 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.8.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.8.1+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful-swagger12 v0.0.0-20170926063155-7524189396c6/go.mod h1:qr0VowGBT4CS4Q8vFF8BSeKz34PuqKGxs/L0IAQA9DQ= +github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= -github.com/evanphx/json-patch v3.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= @@ -218,11 +211,9 @@ github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6 github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= 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.17.2/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/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.17.2/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= @@ -230,7 +221,6 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.4/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/validate v0.17.2/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= 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-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= @@ -260,13 +250,12 @@ github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcr github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20180924190550-6f2cf27854a4/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= 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/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -289,7 +278,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/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= @@ -302,6 +290,7 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= @@ -315,16 +304,13 @@ github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f/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-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= 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/grpc-ecosystem/grpc-gateway v1.5.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.6.3/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-health-probe v0.2.0/go.mod h1:4GVx/bTCtZaSzhjbGueDY5YgBdsmKeVx+LErv/n0L6s= +github.com/grpc-ecosystem/grpc-gateway v1.9.4/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-health-probe v0.2.1-0.20181220223928-2bf0a5b182db/go.mod h1:uBKkC2RbarFsvS5jMJHpVhTLvGlGQj9JJwkaePE3FWI= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -357,11 +343,11 @@ github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGk github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= 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= @@ -377,7 +363,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW 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/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -421,7 +406,7 @@ github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOq github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/maxbrunsfeld/counterfeiter v0.0.0-20181017030959-1aadac120687/go.mod h1:aoVsckWnsNzazwF2kmD+bzgdr4GBlbK91zsdivQJ2eU= +github.com/maxbrunsfeld/counterfeiter/v6 v6.2.1/go.mod h1:F9YacGpnZbLQMzuPI0rR6op21YvNu/RjL705LJJpM3k= github.com/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4= github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY= github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -433,6 +418,7 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -446,6 +432,7 @@ github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwd github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20190414153302-2ae31c8b6b30/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU= 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= @@ -462,7 +449,6 @@ 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/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.2-0.20180831124310-ae19f1b56d53/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= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -471,14 +457,14 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= +github.com/openshift/api v3.9.1-0.20190924102528-32369d4db2ad+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII= github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20181023032605-e838f7fb2186/go.mod h1:Ma5ZXd4S1vmMyewWlF7aO8CZiokR7Sd8dhSfkGkNU4U= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190105193533-81104ffdc4fb/go.mod h1:XMyE4n2opUK4N6L45YGQkXXi8F9fD7XDYFv/CsS6V5I= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20190125151539-1e295784b30a/go.mod h1:vq6TTFvg6ti1Bn6ACsZneZTmjTsURgDD6tQtVDbEgsU= -github.com/operator-framework/operator-registry v1.0.1/go.mod h1:1xEdZjjUg2hPEd52LG3YQ0jtwiwEGdm98S1TH5P4RAA= -github.com/operator-framework/operator-registry v1.0.4/go.mod h1:hve6YwcjM2nGVlscLtNsp9sIIBkNZo6jlJgzWw7vP9s= +github.com/operator-framework/operator-lifecycle-manager v0.0.0-20191115003340-16619cd27fa5/go.mod h1:zL34MNy92LPutBH5gQK+gGhtgTUlZZX03I2G12vWHF4= +github.com/operator-framework/operator-registry v1.5.1/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= github.com/operator-framework/operator-registry v1.5.3/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -488,7 +474,6 @@ github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGB github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/petar/GoLLRB v0.0.0-20130427215148-53be0d36a84c/go.mod h1:HUpKUBZnpzkdx0kD/+Yfuft+uD3zHGtXF/XJB14TUr4= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -499,7 +484,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb 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/pquerna/ffjson v0.0.0-20180717144149-af8b230fcd20/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -512,20 +496,16 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/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-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20190104105734-b1c43a6df3ae/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190104112138-b1a0a9a36d74/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= @@ -551,13 +531,12 @@ github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvf github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sclevine/spec v1.0.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= +github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= 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/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= @@ -571,7 +550,6 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= 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.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= 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= @@ -584,7 +562,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50/go.mod h1:1pdIZTAHUz+HDKDVZ++5xg/duPlhKAIzw9qy42CWYp4= github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -600,11 +577,8 @@ github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= @@ -636,7 +610,6 @@ go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180426230345-b49d69b5da94/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -653,7 +626,6 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 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-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -666,9 +638,7 @@ golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73r 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= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/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-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -686,10 +656,10 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/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-20181105165119-ca4130e427c7/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= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -707,7 +677,6 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20181004145325-8469e314837c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181023152157-44b849a8bc13/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -728,6 +697,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190515120540-06a5c4944438 h1:khxRGsvPk4n2y8I/mLLjp7e5dMTJmH75wvqS6nMwUtY= golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -736,7 +706,6 @@ golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/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= @@ -745,9 +714,7 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181011152555-a398e557df60/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181207222222-4c874b978acb/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -755,12 +722,14 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20191018212557-ed542cd5b28a h1:UuQ+70Pi/ZdWHuP4v457pkXeOynTdgd/4enxeIO/98k= golang.org/x/tools v0.0.0-20191018212557-ed542cd5b28a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= @@ -768,6 +737,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= +gonum.org/v1/gonum v0.0.0-20190710053202-4340aa3071a0/go.mod h1:03dgh78c4UvU1WksguQ/lvJQXbezKQGJSrwwRq5MraQ= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= @@ -780,13 +750,12 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181016170114-94acd270e44e/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-20190404172233-64821d5d2107/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.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -809,7 +778,6 @@ gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= -gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -851,15 +819,12 @@ k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894/go.mod h1:mJUgkl06XV4ks k8s.io/component-base v0.0.0-20191016111319-039242c015a9/go.mod h1:SuWowIgd/dtU/m/iv8OD9eOxp3QZBBhTIiWMsBQvKjI= k8s.io/cri-api v0.0.0-20190828162817-608eb1dad4ac/go.mod h1:BvtUaNBr0fEpzb11OfrQiJLsLPtqbmulpo1fPwcpP6Q= k8s.io/csi-translation-lib v0.0.0-20191016115521-756ffa5af0bd/go.mod h1:lf1VBseeLanBpSXD0N9tuPx1ylI8sA0j6f+rckCKiIk= -k8s.io/gengo v0.0.0-20181106084056-51747d6e00da/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20181113154421-fd15ee9cc2f7/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM= k8s.io/helm v2.16.1+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.1.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c= k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -868,7 +833,6 @@ 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/kube-aggregator v0.0.0-20191016112429-9587704a8ad4/go.mod h1:+aW0UZgSXdTSHTIFnWnueEuXjOqerDUxGIw6Ygr+vYY= k8s.io/kube-controller-manager v0.0.0-20191016114939-2b2b218dc1df/go.mod h1:WgrTcPKYAfNa9C0LV1UeK+XqfbSOUH1WGq/vX5UiW40= -k8s.io/kube-openapi v0.0.0-20181031203759-72693cb1fadd/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190320154901-5e45bb682580/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d h1:Xpe6sK+RY4ZgCTyZ3y273UmFmURhjtoJiwOMbQsXitY= @@ -878,8 +842,7 @@ k8s.io/kube-scheduler v0.0.0-20191016114748-65049c67a58b/go.mod h1:BgDUHHC5Wl0xc k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+IjYA/E= k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51/go.mod h1:gL826ZTIfD4vXTGlmzgTbliCAT9NGiqpCqK2aNYv5MQ= k8s.io/kubelet v0.0.0-20191016114556-7841ed97f1b2/go.mod h1:SBvrtLbuePbJygVXGGCMtWKH07+qrN2dE1iMnteSG8E= -k8s.io/kubernetes v1.11.7-beta.0.0.20181219023948-b875d52ea96d/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/kubernetes v1.11.8-beta.0.0.20190124204751-3a10094374f2/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/kubernetes v1.16.0/go.mod h1:nlP2zevWKRGKuaaVbKIwozU0Rjg9leVDXkL4YTtjmVs= k8s.io/kubernetes v1.16.2/go.mod h1:SmhGgKfQ30imqjFVj8AI+iW+zSyFsswNErKYeTfgoH0= k8s.io/legacy-cloud-providers v0.0.0-20191016115753-cf0698c3a16b/go.mod h1:tKW3pKqdRW8pMveUTpF5pJuCjQxg6a25iLo+Z9BXVH0= k8s.io/metrics v0.0.0-20191016113814-3b1a734dba6e/go.mod h1:ve7/vMWeY5lEBkZf6Bt5TTbGS3b8wAxwGbdXAsufjRs= From a87c6e9d1250a8a695802564d0b228d88821213e Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Wed, 27 Nov 2019 15:45:26 -0800 Subject: [PATCH 27/32] Makefile: ignore all files in test/ in test-unit recipe --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b7b58aa0b88..e82c2e4d73c 100644 --- a/Makefile +++ b/Makefile @@ -183,7 +183,7 @@ test-markdown test/markdown: test-sanity test/sanity: tidy build/operator-sdk ./hack/tests/sanity-check.sh -TEST_PKGS:=$(shell go list ./... | grep -v -P 'github.com/operator-framework/operator-sdk/(hack|test/e2e)') +TEST_PKGS:=$(shell go list ./... | grep -v -P 'github.com/operator-framework/operator-sdk/(hack/|test/)') test-unit test/unit: ## Run the unit tests $(Q)go test -coverprofile=coverage.out -covermode=count -count=1 -short ${TEST_PKGS} From ed368aef7908f43fc64f6a89df33f6c1bf5e72d0 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Mon, 2 Dec 2019 10:11:10 -0800 Subject: [PATCH 28/32] minor changes to integration test script --- hack/tests/integration.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hack/tests/integration.sh b/hack/tests/integration.sh index 6a9b70d56b4..abd2584b76f 100755 --- a/hack/tests/integration.sh +++ b/hack/tests/integration.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -eux +set -eu source hack/lib/image_lib.sh @@ -14,10 +14,10 @@ load_image_if_kind "$OSDK_INTEGRATION_IMAGE" popd # Install OLM on the cluster if not installed. -is_installed=0 +olm_latest_exists=0 if ! operator-sdk alpha olm status > /dev/null 2>&1; then operator-sdk alpha olm install - is_installed=1 + olm_latest_exists=1 fi # Integration tests will use default loading rules for the kubeconfig if @@ -25,7 +25,7 @@ fi go test -v ./test/integration # Uninstall OLM if it was installed for test purposes. -if eval "(( $is_installed ))"; then +if eval "(( $olm_latest_exists ))"; then operator-sdk alpha olm uninstall fi From ea728e3951a6550f52e3cb55af603fd64942a32a Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Mon, 2 Dec 2019 16:49:29 -0800 Subject: [PATCH 29/32] check errs --- internal/olm/operator/internal/configmap.go | 2 +- internal/olm/operator/tenancy.go | 2 +- test/integration/operator_olm_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/olm/operator/internal/configmap.go b/internal/olm/operator/internal/configmap.go index d7fa4ff5bd0..dedd304c213 100644 --- a/internal/olm/operator/internal/configmap.go +++ b/internal/olm/operator/internal/configmap.go @@ -74,7 +74,7 @@ func (m *RegistryResources) IsManifestDataStale(ctx context.Context, namespace s // hashContents creates a base32-encoded md5 digest of b's bytes. func hashContents(b []byte) string { h := md5.New() - h.Write(b) + _, _ = h.Write(b) enc := base32.StdEncoding.WithPadding(base32.NoPadding) return enc.EncodeToString(h.Sum(nil)) } diff --git a/internal/olm/operator/tenancy.go b/internal/olm/operator/tenancy.go index 4f0fb8f041f..d7291f6293f 100644 --- a/internal/olm/operator/tenancy.go +++ b/internal/olm/operator/tenancy.go @@ -258,7 +258,7 @@ func validateInstallModeWithNamespaces(mode olmapiv1alpha1.InstallModeType, name return errors.Errorf("installMode %s must be passed with exactly one empty namespace, have: %+q", mode, namespaces) } default: - errors.Errorf("installMode %q is not a valid installMode type", mode) + return errors.Errorf("installMode %q is not a valid installMode type", mode) } return nil } diff --git a/test/integration/operator_olm_test.go b/test/integration/operator_olm_test.go index 4c0ef17cad6..18d81de5eab 100644 --- a/test/integration/operator_olm_test.go +++ b/test/integration/operator_olm_test.go @@ -102,7 +102,7 @@ func SingleOperator(t *testing.T) { } defer func() { opcmd.Force = true - opcmd.Down() + _ = opcmd.Down() os.RemoveAll(tmp) }() for _, c := range cases { From c489e8011096a6901d0f255492a279e8438668c5 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 3 Dec 2019 14:42:32 -0800 Subject: [PATCH 30/32] fix spelling --- internal/olm/operator/tenancy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/olm/operator/tenancy.go b/internal/olm/operator/tenancy.go index d7291f6293f..15506e29943 100644 --- a/internal/olm/operator/tenancy.go +++ b/internal/olm/operator/tenancy.go @@ -263,7 +263,7 @@ func validateInstallModeWithNamespaces(mode olmapiv1alpha1.InstallModeType, name return nil } -// getOperatorGroupInNamespace gets the OperatorGroup in namespace. Becuase +// getOperatorGroupInNamespace gets the OperatorGroup in namespace. Because // there must only be one OperatorGroup per namespace, an error is returned // if more than one is found. nil is returned if no OperatorGroup exists in // namespace. From 94382d278d904ad55043358deb0354a976cbd627 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 3 Dec 2019 15:45:46 -0800 Subject: [PATCH 31/32] fix linter errors --- internal/util/operator-registry/validate.go | 79 --------------------- test/integration/test_suite.go | 10 +-- 2 files changed, 5 insertions(+), 84 deletions(-) diff --git a/internal/util/operator-registry/validate.go b/internal/util/operator-registry/validate.go index dea5e4523c4..7ef451b48b4 100644 --- a/internal/util/operator-registry/validate.go +++ b/internal/util/operator-registry/validate.go @@ -17,11 +17,8 @@ package registry import ( "fmt" - olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-registry/pkg/appregistry" "github.com/operator-framework/operator-registry/pkg/registry" "github.com/pkg/errors" - apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" ) // ValidatePackageManifest ensures each datum in pkg is valid relative to other @@ -57,79 +54,3 @@ func ValidatePackageManifest(pkg *registry.PackageManifest) error { return nil } - -// validateBundle ensures all objects in bundle have the correct data. -// TODO(estroz): remove once operator-verify library is complete. -func validateBundle(bundle *registry.Bundle) (err error) { - bcsv, err := bundle.ClusterServiceVersion() - if err != nil { - return err - } - csv := MustBundleCSVToCSV(bcsv) - crds, err := bundle.CustomResourceDefinitions() - if err != nil { - return err - } - crdMap := map[string]struct{}{} - for _, crd := range crds { - for _, k := range getCRDKeys(crd) { - crdMap[k.String()] = struct{}{} - } - } - // If at least one CSV has an owned CRD it must be present. - if len(csv.Spec.CustomResourceDefinitions.Owned) > 0 && len(crds) == 0 { - return errors.Errorf("bundled CSV has an owned CRD but no CRD's are present in bundle dir") - } - // Ensure all CRD's referenced in each CSV exist in BundleDir. - for _, o := range csv.Spec.CustomResourceDefinitions.Owned { - key := getCRDDescKey(o) - if _, hasCRD := crdMap[key.String()]; !hasCRD { - return errors.Errorf("bundle dir does not contain owned CRD %q from CSV %q", key, csv.GetName()) - } - } - if !hasSupportedInstallMode(csv) { - return errors.Errorf("at least one installMode must be marked \"supported\" in CSV %q", csv.GetName()) - } - return nil -} - -// hasSupportedInstallMode returns true if a csv supports at least one -// installMode. -func hasSupportedInstallMode(csv *olmapiv1alpha1.ClusterServiceVersion) bool { - for _, mode := range csv.Spec.InstallModes { - if mode.Supported { - return true - } - } - return false -} - -// getCRDKeys returns a key uniquely identifying crd. -func getCRDDescKey(crd olmapiv1alpha1.CRDDescription) appregistry.CRDKey { - return appregistry.CRDKey{ - Kind: crd.Kind, - Name: crd.Name, - Version: crd.Version, - } -} - -// getCRDKeys returns a set of keys uniquely identifying crd per version. -// getCRDKeys assumes at least one of spec.version, spec.versions is non-empty. -func getCRDKeys(crd *apiextv1beta1.CustomResourceDefinition) (keys []appregistry.CRDKey) { - if crd.Spec.Version != "" && len(crd.Spec.Versions) == 0 { - return []appregistry.CRDKey{{ - Kind: crd.Spec.Names.Kind, - Name: crd.GetName(), - Version: crd.Spec.Version, - }, - } - } - for _, v := range crd.Spec.Versions { - keys = append(keys, appregistry.CRDKey{ - Kind: crd.Spec.Names.Kind, - Name: crd.GetName(), - Version: v.Name, - }) - } - return keys -} diff --git a/test/integration/test_suite.go b/test/integration/test_suite.go index 83ac405c6b0..4c281fc0099 100644 --- a/test/integration/test_suite.go +++ b/test/integration/test_suite.go @@ -23,10 +23,10 @@ import ( "strings" "github.com/ghodss/yaml" - opv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/operator-framework/operator-registry/pkg/registry" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -52,7 +52,7 @@ type CSVTemplateConfig struct { Maturity string ReplacesCSVName string CRDKeys []DefinitionKey - InstallModes []opv1alpha1.InstallMode + InstallModes []operatorsv1alpha1.InstallMode } const csvTmpl = `apiVersion: operators.coreos.com/v1alpha1 @@ -215,11 +215,11 @@ func writeOperatorManifests(root, operatorName, defaultChannel string, csvConfig bundleDir := filepath.Join(manifestsDir, csvConfig.OperatorVersion) for _, key := range csvConfig.CRDKeys { crd := apiextv1beta1.CustomResourceDefinition{ - TypeMeta: v1.TypeMeta{ + TypeMeta: metav1.TypeMeta{ APIVersion: apiextv1beta1.SchemeGroupVersion.String(), Kind: "CustomResourceDefinition", }, - ObjectMeta: v1.ObjectMeta{Name: key.Name}, + ObjectMeta: metav1.ObjectMeta{Name: key.Name}, Spec: apiextv1beta1.CustomResourceDefinitionSpec{ Names: apiextv1beta1.CustomResourceDefinitionNames{ Kind: key.Kind, From 5e150cc2d8b21c269a37ae313089fe13db45f272 Mon Sep 17 00:00:00 2001 From: Eric Stroczynski Date: Tue, 10 Dec 2019 11:46:12 -0800 Subject: [PATCH 32/32] update status method name after merge --- internal/olm/operator/manager.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/internal/olm/operator/manager.go b/internal/olm/operator/manager.go index 66984dcac0e..bc24caaf901 100644 --- a/internal/olm/operator/manager.go +++ b/internal/olm/operator/manager.go @@ -193,8 +193,11 @@ func (m *operatorManager) up(ctx context.Context) (err error) { return err } u := unstructured.Unstructured{Object: obj} - if status := m.status(ctx, &u); status.HasExistingResources() { + status := m.status(ctx, &u) + if installed, err := status.HasInstalledResources(); installed { return errors.Errorf("an operator with name %q is already running\n%s", pkgName, status) + } else if err != nil { + return errors.Errorf("an operator with name %q is present and has resource errors\n%s", pkgName, status) } } @@ -307,8 +310,11 @@ func (m *operatorManager) down(ctx context.Context) (err error) { return err } if !m.force { - if status := m.status(ctx, bundle.Objects...); !status.HasExistingResources() { + status := m.status(ctx, bundle.Objects...) + if installed, err := status.HasInstalledResources(); !installed { return errors.Errorf("no operator with name %q is running", pkgName) + } else if err != nil { + return errors.Errorf("an operator with name %q is present and has resource errors\n%s", pkgName, status) } } @@ -339,8 +345,10 @@ func (m *operatorManager) down(ctx context.Context) (err error) { } status := m.status(ctx, bundle.Objects...) - if status.HasExistingResources() { - return errors.Errorf("operator %q resources still exist\n%s", csv.GetName(), status) + if installed, err := status.HasInstalledResources(); installed { + return errors.Errorf("an operator with name %q still exists", pkgName) + } else if err != nil { + return errors.Errorf("an operator with name %q is present and has resource errors\n%s", pkgName, status) } log.Infof("Successfully uninstalled %q on OLM version %q", csv.GetName(), olmVer)