From 9e1c77a7bec44a4c019740308950a3c67f713708 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 27 Oct 2022 14:32:24 -0400 Subject: [PATCH 01/43] Change uses to point to Git hash --- .github/workflows/test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 93e4923f39..4f7d12cce4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -344,7 +344,11 @@ jobs: acceptance: needs: [ get-product-version, dev-upload-docker, get-go-version ] +<<<<<<< HEAD uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@main +======= + uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@536f034d6647fdadca8892036d0b06e28d1c9a57 +>>>>>>> d5d87e8c (Change uses to point to Git hash) with: name: acceptance directory: acceptance/tests From 7fa8bdc53f8a379f14e1e8796b1dcd51752f1ab7 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 13 Oct 2022 16:16:34 -0400 Subject: [PATCH 02/43] Update Go client dep --- cli/go.mod | 48 +++++++------- cli/go.sum | 184 +++++++++++++++++++---------------------------------- 2 files changed, 89 insertions(+), 143 deletions(-) diff --git a/cli/go.mod b/cli/go.mod index 53763dcb7f..76d685a257 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -6,7 +6,7 @@ require ( github.com/bgentry/speakeasy v0.1.0 github.com/cenkalti/backoff v2.2.1+incompatible github.com/fatih/color v1.13.0 - github.com/google/go-cmp v0.5.6 + github.com/google/go-cmp v0.5.8 github.com/hashicorp/consul-k8s/charts v0.0.0-00010101000000-000000000000 github.com/hashicorp/go-hclog v0.16.2 github.com/hashicorp/hcp-sdk-go v0.23.1-0.20220921131124-49168300a7dc @@ -18,11 +18,12 @@ require ( github.com/stretchr/testify v1.7.2 golang.org/x/text v0.3.7 helm.sh/helm/v3 v3.9.4 - k8s.io/api v0.24.3 - k8s.io/apimachinery v0.24.3 + k8s.io/api v0.25.0 + k8s.io/apimachinery v0.25.0 k8s.io/cli-runtime v0.24.3 - k8s.io/client-go v0.24.3 - k8s.io/utils v0.0.0-20220713171938-56c0de1e6f5e + k8s.io/client-go v0.25.0 + k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed + sigs.k8s.io/controller-runtime v0.13.0 sigs.k8s.io/yaml v1.3.0 ) @@ -30,8 +31,8 @@ require ( cloud.google.com/go v0.99.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.24 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect + github.com/Azure/go-autorest/autorest v0.11.27 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect @@ -62,10 +63,11 @@ require ( github.com/docker/go-units v0.4.0 // indirect github.com/emicklei/go-restful/v3 v3.8.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-gorp/gorp/v3 v3.0.2 // indirect - github.com/go-logr/logr v1.2.2 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/analysis v0.20.0 // indirect github.com/go-openapi/errors v0.20.2 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect @@ -126,7 +128,7 @@ require ( github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect + github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect @@ -145,30 +147,30 @@ require ( go.mongodb.org/mongo-driver v1.4.6 // indirect go.starlark.net v0.0.0-20200707032745-474f21a9602d // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect - golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect - golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect - golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect + golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect + golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 // indirect - google.golang.org/grpc v1.43.0 // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect + google.golang.org/grpc v1.47.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.24.2 // indirect - k8s.io/apiserver v0.24.2 // indirect - k8s.io/component-base v0.24.2 // indirect - k8s.io/klog/v2 v2.60.1 // indirect - k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect + k8s.io/apiextensions-apiserver v0.25.0 // indirect + k8s.io/apiserver v0.25.0 // indirect + k8s.io/component-base v0.25.0 // indirect + k8s.io/klog/v2 v2.70.1 // indirect + k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect k8s.io/kubectl v0.24.2 // indirect oras.land/oras-go v1.2.0 // indirect - sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/kustomize/api v0.11.4 // indirect sigs.k8s.io/kustomize/kyaml v0.13.6 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect ) // This replace directive is to avoid having to manually bump the version of the charts module upon changes to the Helm diff --git a/cli/go.sum b/cli/go.sum index fedf1a3dd9..c8affbd2ae 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -51,15 +51,17 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6 github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.24 h1:1fIGgHKqVm54KIPT+q8Zmd1QlVsmHqeUGso5qm2BqqE= -github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= +github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A= +github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.20 h1:gJ3E98kMpFB1MFqQCvA1yFab8vthOeD4VlFRQULxahg= +github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= @@ -87,7 +89,6 @@ github.com/Masterminds/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA4 github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= github.com/Microsoft/hcsshim v0.9.3 h1:k371PzBuRrz2b+ebGuI2nVgVhgsVX60jMfSw80NECxo= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= @@ -103,7 +104,6 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= @@ -125,7 +125,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= @@ -135,8 +134,6 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXe github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= @@ -152,22 +149,14 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0= github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -181,8 +170,6 @@ 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/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -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/distribution/distribution/v3 v3.0.0-20220526142353-ffbd94cbe269 h1:hbCT8ZPPMqefiAWD2ZKjn7ypokIGViTvBBg/ExLSdCk= github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -202,7 +189,6 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -216,11 +202,13 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= @@ -232,11 +220,10 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -256,9 +243,10 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= 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.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -392,8 +380,6 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= @@ -401,8 +387,6 @@ github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8 github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -443,8 +427,6 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.10.1/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= -github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -458,8 +440,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -504,10 +487,6 @@ github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -550,12 +529,12 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= 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/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -575,7 +554,6 @@ github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaR github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -608,7 +586,6 @@ github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -656,7 +633,6 @@ github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFW github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -699,9 +675,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= @@ -709,7 +684,7 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -719,10 +694,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= @@ -741,22 +714,19 @@ github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg= github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= @@ -764,15 +734,12 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/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/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -797,35 +764,27 @@ github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= 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/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -843,8 +802,6 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= @@ -854,7 +811,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -869,18 +825,9 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMzt github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q= -go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= -go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= -go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= @@ -898,7 +845,6 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= @@ -912,14 +858,14 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20200707032745-474f21a9602d h1:uFqwFYlX7d5ZSp+IqhXxct0SybXrTzEBDvb2CkEhPBs= go.starlark.net v0.0.0-20200707032745-474f21a9602d/go.mod h1:f0znQkUKRrkk36XxWbGjMqQM8wGv/xHBVE2qc3B5oFU= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -985,7 +931,6 @@ golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1028,12 +973,11 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1064,14 +1008,13 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20181026203630-95b1ffbd15a5/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1117,7 +1060,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1141,7 +1083,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1149,8 +1090,8 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1167,10 +1108,9 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1242,8 +1182,8 @@ golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1304,7 +1244,6 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1316,7 +1255,6 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1344,8 +1282,9 @@ google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 h1:Et6SkiuvnBn+SgrSYXs/BrUpGB4mbdwt4R3vaPIlicA= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1371,8 +1310,9 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1386,8 +1326,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1399,14 +1340,9 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -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= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1435,51 +1371,58 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg= -k8s.io/api v0.24.3 h1:tt55QEmKd6L2k5DP6G/ZzdMQKvG5ro4H4teClqm0sTY= k8s.io/api v0.24.3/go.mod h1:elGR/XSZrS7z7cSZPzVWaycpJuGIw57j9b95/1PdJNI= -k8s.io/apiextensions-apiserver v0.24.2 h1:/4NEQHKlEz1MlaK/wHT5KMKC9UKYz6NZz6JE6ov4G6k= -k8s.io/apiextensions-apiserver v0.24.2/go.mod h1:e5t2GMFVngUEHUd0wuCJzw8YDwZoqZfJiGOW6mm2hLQ= +k8s.io/api v0.25.0 h1:H+Q4ma2U/ww0iGB78ijZx6DRByPz6/733jIuFpX70e0= +k8s.io/api v0.25.0/go.mod h1:ttceV1GyV1i1rnmvzT3BST08N6nGt+dudGrquzVQWPk= +k8s.io/apiextensions-apiserver v0.25.0 h1:CJ9zlyXAbq0FIW8CD7HHyozCMBpDSiH7EdrSTCZcZFY= +k8s.io/apiextensions-apiserver v0.25.0/go.mod h1:3pAjZiN4zw7R8aZC5gR0y3/vCkGlAjCazcg1me8iB/E= k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/apimachinery v0.24.3 h1:hrFiNSA2cBZqllakVYyH/VyEh4B581bQRmqATJSeQTg= k8s.io/apimachinery v0.24.3/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/apiserver v0.24.2 h1:orxipm5elPJSkkFNlwH9ClqaKEDJJA3yR2cAAlCnyj4= -k8s.io/apiserver v0.24.2/go.mod h1:pSuKzr3zV+L+MWqsEo0kHHYwCo77AT5qXbFXP2jbvFI= +k8s.io/apimachinery v0.25.0 h1:MlP0r6+3XbkUG2itd6vp3oxbtdQLQI94fD5gCS+gnoU= +k8s.io/apimachinery v0.25.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0= +k8s.io/apiserver v0.25.0 h1:8kl2ifbNffD440MyvHtPaIz1mw4mGKVgWqM0nL+oyu4= +k8s.io/apiserver v0.25.0/go.mod h1:BKwsE+PTC+aZK+6OJQDPr0v6uS91/HWxX7evElAH6xo= k8s.io/cli-runtime v0.24.2/go.mod h1:1LIhKL2RblkhfG4v5lZEt7FtgFG5mVb8wqv5lE9m5qY= k8s.io/cli-runtime v0.24.3 h1:O9YvUHrDSCQUPlsqVmaqDrueqjpJ7IO6Yas9B6xGSoo= k8s.io/cli-runtime v0.24.3/go.mod h1:In84wauoMOqa7JDvDSXGbf8lTNlr70fOGpYlYfJtSqA= k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30= -k8s.io/client-go v0.24.3 h1:Nl1840+6p4JqkFWEW2LnMKU667BUxw03REfLAVhuKQY= k8s.io/client-go v0.24.3/go.mod h1:AAovolf5Z9bY1wIg2FZ8LPQlEdKHjLI7ZD4rw920BJw= +k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E= +k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8= k8s.io/code-generator v0.24.2/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w= -k8s.io/component-base v0.24.2 h1:kwpQdoSfbcH+8MPN4tALtajLDfSfYxBDYlXobNWI6OU= k8s.io/component-base v0.24.2/go.mod h1:ucHwW76dajvQ9B7+zecZAP3BVqvrHoOxm8olHEg0nmM= +k8s.io/component-base v0.25.0 h1:haVKlLkPCFZhkcqB6WCvpVxftrg6+FK5x1ZuaIDaQ5Y= +k8s.io/component-base v0.25.0/go.mod h1:F2Sumv9CnbBlqrpdf7rKZTmmd2meJq0HizeyY/yAFxk= k8s.io/component-helpers v0.24.2/go.mod h1:TRQPBQKfmqkmV6c0HAmUs8cXVNYYYLsXy4zu8eODi9g= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= +k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 h1:yEQKdMCjzAOvGeiTwG4hO/hNVNtDOuUFvMUZ0OlaIzs= -k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8/go.mod h1:mbJ+NSUoAhuR14N0S63bPkh8MGVSo3VYSGZtH/mfMe0= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= k8s.io/kubectl v0.24.2 h1:+RfQVhth8akUmIc2Ge8krMl/pt66V7210ka3RE/p0J4= k8s.io/kubectl v0.24.2/go.mod h1:+HIFJc0bA6Tzu5O/YcuUt45APAxnNL8LeMuXwoiGsPg= k8s.io/metrics v0.24.2/go.mod h1:5NWURxZ6Lz5gj8TFU83+vdWIVASx7W8lwPpHYCqopMo= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220713171938-56c0de1e6f5e h1:W1yba+Bpkwb5BatGKZALQ1yylhwnuD6CkYmrTibyLDM= -k8s.io/utils v0.0.0-20220713171938-56c0de1e6f5e/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= oras.land/oras-go v1.2.0 h1:yoKosVIbsPoFMqAIFHTnrmOuafHal+J/r+I5bdbVWu4= oras.land/oras-go v1.2.0/go.mod h1:pFNs7oHp2dYsYMSS82HaX5l4mpnGO7hbpPN6EWH2ltc= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.11.4 h1:/0Mr3kfBBNcNPOW5Qwk/3eb8zkswCwnqQxxKtmrTkRo= sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI= sigs.k8s.io/kustomize/cmd/config v0.10.6/go.mod h1:/S4A4nUANUa4bZJ/Edt7ZQTyKOY9WCER0uBS1SW2Rco= @@ -1487,8 +1430,9 @@ sigs.k8s.io/kustomize/kustomize/v4 v4.5.4/go.mod h1:Zo/Xc5FKD6sHl0lilbrieeGeZHVY sigs.k8s.io/kustomize/kyaml v0.13.6 h1:eF+wsn4J7GOAXlvajv6OknSunxpcOBQQqsnPxObtkGs= sigs.k8s.io/kustomize/kyaml v0.13.6/go.mod h1:yHP031rn1QX1lr/Xd934Ri/xdVNG8BE2ECa78Ht/kEg= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= From 22e8ee3934663644d52c8066b22ee81b296db2b4 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 18 Oct 2022 10:45:57 -0400 Subject: [PATCH 03/43] Rework to patch CRs --- cli/cmd/uninstall/crds.go | 118 +++++++++++++++++++++++++++++++++ cli/cmd/uninstall/uninstall.go | 27 ++++++++ 2 files changed, 145 insertions(+) create mode 100644 cli/cmd/uninstall/crds.go diff --git a/cli/cmd/uninstall/crds.go b/cli/cmd/uninstall/crds.go new file mode 100644 index 0000000000..6b2d6f6a17 --- /dev/null +++ b/cli/cmd/uninstall/crds.go @@ -0,0 +1,118 @@ +package uninstall + +import ( + "context" + "encoding/json" + "fmt" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const ( + crdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" + consulGroup = "consul.hashicorp.com" +) + +// crds is used to deserialize JSON returned from the +// `/apis/apiextensions.k8s.io/v1/customresourcedefinitions` endpoint. +type crds struct { + Items []crd `json:"items"` +} + +// crd is used to deserialize the JSON definition of a single CRD. +type crd struct { + Metadata struct { + Name string `json:"name"` + } `json:"metadata"` + Spec struct { + Group string `json:"group"` + Names struct { + Kind string `json:"kind"` + } `json:"names"` + Versions []struct { + Name string `json:"name"` + } `json:"versions"` + } `json:"spec"` +} + +// crs is used to deserialize JSON returned from the +// `/apis/consul.hashicorp.com//` endpoint. +type crs struct { + Items []cr `json:"items"` +} + +// cr is used to deserialize the JSOn definition of a single CR. +type cr struct { + Kind string `json:"kind"` + Metadata struct { + Name string `json:"name"` + Namespace string `json:"namespace"` + Uid string `json:"uid"` + } `json:"metadata"` +} + +// patchCustomResources removes the finalizers from all custom resources +// managed by Consul. This allows them to be removed from the Kubernetes cluster. +func patchCustomResources(ctx context.Context, restClient rest.Interface, client client.Client) error { + // Get all custom resource definitions in the Kubernetes cluster. + raw, err := restClient.Get().AbsPath(crdPath).DoRaw(ctx) + if err != nil { + return nil + } + var allCRDs crds + if err := json.Unmarshal(raw, &allCRDs); err != nil { + return err + } + + // Filter only to CRDs managed by Consul. + var consulCRDs crds + for _, crd := range allCRDs.Items { + if crd.Spec.Group == consulGroup { + consulCRDs.Items = append(consulCRDs.Items, crd) + } + } + if len(consulCRDs.Items) == 0 { + return nil + } + + // Get all custom resources for each custom resource definition. + var consulCRs []cr + for _, crd := range consulCRDs.Items { + for _, path := range crPaths(crd) { + raw, err := restClient.Get().AbsPath(path).DoRaw(ctx) + if err != nil { + return err + } + var crs crs + if err := json.Unmarshal(raw, &crs); err != nil { + return err + } + consulCRs = append(consulCRs, crs.Items...) + } + } + + // Patch the finalizers for each custom resource. + var target = &unstructured.Unstructured{} + for _, cr := range consulCRs { + target.SetNamespace(cr.Metadata.Namespace) + target.SetName(cr.Metadata.Name) + target.SetKind(cr.Kind) + + if err := client.Patch(ctx, target, nil); err != nil { + return err + } + } + + return nil +} + +// crPaths returns a Kubernetes API path to the custom resources +// for each version of the custom resource definition. +func crPaths(crd crd) []string { + var paths []string + for _, version := range crd.Spec.Versions { + paths = append(paths, fmt.Sprintf("/apis/%s/%s/%s", consulGroup, version, crd.Spec.Names.Kind)) + } + return paths +} diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 28a7e969b6..06ebc7dcfb 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -3,6 +3,7 @@ package uninstall import ( "fmt" "os" + "os/exec" "sync" "time" @@ -345,6 +346,12 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin } } + if releaseType == common.ReleaseTypeConsul { + if err := c.deleteCustomResources(); err != nil { + return err + } + } + actionConfig, err := helm.InitActionConfig(actionConfig, namespace, settings, uiLogger) if err != nil { return err @@ -361,10 +368,30 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin c.UI.Output("Uninstall result: %s", res.Info, terminal.WithInfoStyle()) return nil } + + if releaseType == common.ReleaseTypeConsul { + if err := c.patchCustomResources(); err != nil { + return err + } + } + c.UI.Output(fmt.Sprintf("Successfully uninstalled %s Helm release.", releaseType), terminal.WithSuccessStyle()) return nil } +func (c *Command) deleteCustomResources() error { + for _, kind := range []string{"exported-services", "ingress-gateways", "meshes", "proxy-defaults", "service-defaults", "service-intentions", "service-resolvers", "service-routers", "service-splitters", "terminating-gateways"} { + out, err := exec.Command("kubectl", "delete", kind, "-A", "--all").Output() + c.UI.Output(string(out)) + c.UI.Output(err.Error()) + } + return nil +} + +func (c *Command) patchCustomResources() error { + return nil +} + func (c *Command) Help() string { c.once.Do(c.init) s := "Usage: consul-k8s uninstall [flags]" + "\n" + "Uninstall Consul with options to delete data and resources associated with Consul installation." + "\n\n" + c.help From 8ec67d21bdc8c3c5b06b13bd7cd67e56e61acd30 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 18 Oct 2022 22:29:52 -0400 Subject: [PATCH 04/43] Delete and patch CRs --- cli/cmd/uninstall/crds.go | 118 -------------------- cli/cmd/uninstall/uninstall.go | 165 +++++++++++++++++++++++++++- cli/cmd/uninstall/uninstall_test.go | 3 + cli/common/finalizer.go | 23 ++++ 4 files changed, 186 insertions(+), 123 deletions(-) delete mode 100644 cli/cmd/uninstall/crds.go create mode 100644 cli/common/finalizer.go diff --git a/cli/cmd/uninstall/crds.go b/cli/cmd/uninstall/crds.go deleted file mode 100644 index 6b2d6f6a17..0000000000 --- a/cli/cmd/uninstall/crds.go +++ /dev/null @@ -1,118 +0,0 @@ -package uninstall - -import ( - "context" - "encoding/json" - "fmt" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -const ( - crdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" - consulGroup = "consul.hashicorp.com" -) - -// crds is used to deserialize JSON returned from the -// `/apis/apiextensions.k8s.io/v1/customresourcedefinitions` endpoint. -type crds struct { - Items []crd `json:"items"` -} - -// crd is used to deserialize the JSON definition of a single CRD. -type crd struct { - Metadata struct { - Name string `json:"name"` - } `json:"metadata"` - Spec struct { - Group string `json:"group"` - Names struct { - Kind string `json:"kind"` - } `json:"names"` - Versions []struct { - Name string `json:"name"` - } `json:"versions"` - } `json:"spec"` -} - -// crs is used to deserialize JSON returned from the -// `/apis/consul.hashicorp.com//` endpoint. -type crs struct { - Items []cr `json:"items"` -} - -// cr is used to deserialize the JSOn definition of a single CR. -type cr struct { - Kind string `json:"kind"` - Metadata struct { - Name string `json:"name"` - Namespace string `json:"namespace"` - Uid string `json:"uid"` - } `json:"metadata"` -} - -// patchCustomResources removes the finalizers from all custom resources -// managed by Consul. This allows them to be removed from the Kubernetes cluster. -func patchCustomResources(ctx context.Context, restClient rest.Interface, client client.Client) error { - // Get all custom resource definitions in the Kubernetes cluster. - raw, err := restClient.Get().AbsPath(crdPath).DoRaw(ctx) - if err != nil { - return nil - } - var allCRDs crds - if err := json.Unmarshal(raw, &allCRDs); err != nil { - return err - } - - // Filter only to CRDs managed by Consul. - var consulCRDs crds - for _, crd := range allCRDs.Items { - if crd.Spec.Group == consulGroup { - consulCRDs.Items = append(consulCRDs.Items, crd) - } - } - if len(consulCRDs.Items) == 0 { - return nil - } - - // Get all custom resources for each custom resource definition. - var consulCRs []cr - for _, crd := range consulCRDs.Items { - for _, path := range crPaths(crd) { - raw, err := restClient.Get().AbsPath(path).DoRaw(ctx) - if err != nil { - return err - } - var crs crs - if err := json.Unmarshal(raw, &crs); err != nil { - return err - } - consulCRs = append(consulCRs, crs.Items...) - } - } - - // Patch the finalizers for each custom resource. - var target = &unstructured.Unstructured{} - for _, cr := range consulCRs { - target.SetNamespace(cr.Metadata.Namespace) - target.SetName(cr.Metadata.Name) - target.SetKind(cr.Kind) - - if err := client.Patch(ctx, target, nil); err != nil { - return err - } - } - - return nil -} - -// crPaths returns a Kubernetes API path to the custom resources -// for each version of the custom resource definition. -func crPaths(crd crd) []string { - var paths []string - for _, version := range crd.Spec.Versions { - paths = append(paths, fmt.Sprintf("/apis/%s/%s/%s", consulGroup, version, crd.Spec.Names.Kind)) - } - return paths -} diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 06ebc7dcfb..a2a14dcedf 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -1,9 +1,12 @@ package uninstall import ( + "context" + "encoding/json" "fmt" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "os" - "os/exec" "sync" "time" @@ -19,6 +22,8 @@ import ( helmCLI "helm.sh/helm/v3/pkg/cli" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" ) const ( @@ -39,6 +44,9 @@ const ( flagContext = "context" flagKubeconfig = "kubeconfig" + + crdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" + consulGroup = "consul.hashicorp.com" ) type Command struct { @@ -46,7 +54,10 @@ type Command struct { helmActionsRunner helm.HelmActionsRunner + // Configuration for interacting with Kubernetes. kubernetes kubernetes.Interface + client client.Client + restClient rest.Interface set *flag.Sets @@ -175,6 +186,15 @@ func (c *Command) Run(args []string) int { c.UI.Output("initializing Kubernetes client: %v", err, terminal.WithErrorStyle()) return 1 } + if c.restClient == nil { + c.restClient = c.kubernetes.CoreV1().RESTClient() + } + if c.client == nil { + if c.client, err = client.New(restConfig, client.Options{}); err != nil { + c.UI.Output("error creating Kubernetes client %v", err, terminal.WithErrorStyle()) + return 1 + } + } } // Setup logger to stream Helm library logs. @@ -379,19 +399,154 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil } +// crds is used to deserialize JSON returned from the +// `/apis/apiextensions.k8s.io/v1/customresourcedefinitions` endpoint. +type crds struct { + Items []crd `json:"items"` +} + +// crd is used to deserialize the JSON definition of a single CRD. +type crd struct { + Metadata struct { + Name string `json:"name"` + } `json:"metadata"` + Spec struct { + Group string `json:"group"` + Names struct { + Kind string `json:"kind"` + } `json:"names"` + Versions []struct { + Name string `json:"name"` + } `json:"versions"` + } `json:"spec"` +} + +// crs is used to deserialize JSON returned from the +// `/apis/consul.hashicorp.com//` endpoint. +type crs struct { + Items []cr `json:"items"` +} + +// cr is used to deserialize the JSOn definition of a single CR. +type cr struct { + Kind string `json:"kind"` + Metadata struct { + Name string `json:"name"` + Namespace string `json:"namespace"` + Uid string `json:"uid"` + } `json:"metadata"` +} + +// deleteCustomResources gets a list of all custom resource definitions managed +// by Consul. It then iterates over all custom resources matching these +// definitions and deletes them. A timeout is attached to each deletion in order +// to circumvent any deadlock issues which may arise. func (c *Command) deleteCustomResources() error { - for _, kind := range []string{"exported-services", "ingress-gateways", "meshes", "proxy-defaults", "service-defaults", "service-intentions", "service-resolvers", "service-routers", "service-splitters", "terminating-gateways"} { - out, err := exec.Command("kubectl", "delete", kind, "-A", "--all").Output() - c.UI.Output(string(out)) - c.UI.Output(err.Error()) + c.UI.Output("Deleting any Consul custom resources that may exist.", terminal.WithLibraryStyle()) + + raw, err := c.restClient.Get().AbsPath(crdPath).DoRaw(c.Ctx) + if err != nil { + return err + } + var crds crds + if err := json.Unmarshal(raw, &crds); err != nil { + return err + } + + namespaces, err := c.kubernetes.CoreV1().Namespaces().List(c.Ctx, metav1.ListOptions{}) + if err != nil { + return err + } + + for _, crd := range crds.Items { + if crd.Spec.Group == "consul.hashicorp.com" { + for _, version := range crd.Spec.Versions { + for _, namespace := range namespaces.Items { + ctx, _ := context.WithTimeout(c.Ctx, time.Minute) + + cr := &unstructured.Unstructured{} + cr.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "consul.hashicorp.com", + Kind: crd.Spec.Names.Kind, + Version: version.Name, + }) + err = c.client.DeleteAllOf(ctx, cr, client.InNamespace(namespace.Name)) + if err != nil { + return err + } + } + } + } } + return nil } func (c *Command) patchCustomResources() error { + c.UI.Output("Patching finalizers for Consul custom resources.", terminal.WithLibraryStyle()) + + // Get all custom resource definitions in the Kubernetes cluster. + raw, err := c.restClient.Get().AbsPath(crdPath).DoRaw(c.Ctx) + if err != nil { + return nil + } + var allCRDs crds + if err := json.Unmarshal(raw, &allCRDs); err != nil { + return err + } + + // Filter only to CRDs managed by Consul. + var consulCRDs crds + for _, crd := range allCRDs.Items { + if crd.Spec.Group == consulGroup { + consulCRDs.Items = append(consulCRDs.Items, crd) + } + } + if len(consulCRDs.Items) == 0 { + return nil + } + + // Get all custom resources for each custom resource definition. + var consulCRs []cr + for _, crd := range consulCRDs.Items { + for _, path := range crPaths(crd) { + raw, err := c.restClient.Get().AbsPath(path).DoRaw(c.Ctx) + if err != nil { + return err + } + var crs crs + if err := json.Unmarshal(raw, &crs); err != nil { + return err + } + consulCRs = append(consulCRs, crs.Items...) + } + } + + // Patch the finalizers for each custom resource. + var target = &unstructured.Unstructured{} + for _, cr := range consulCRs { + target.SetNamespace(cr.Metadata.Namespace) + target.SetName(cr.Metadata.Name) + target.SetKind(cr.Kind) + + if err := c.client.Patch(c.Ctx, target, common.NewFinalizer()); err != nil { + return err + } + } + return nil } +// crPaths returns a Kubernetes API path to the custom resources +// for each version of the custom resource definition. +func crPaths(crd crd) []string { + var paths []string + for _, version := range crd.Spec.Versions { + paths = append(paths, fmt.Sprintf("/apis/%s/%s/%s", consulGroup, version, crd.Spec.Names.Kind)) + } + return paths +} + func (c *Command) Help() string { c.once.Do(c.init) s := "Usage: consul-k8s uninstall [flags]" + "\n" + "Uninstall Consul with options to delete data and resources associated with Consul installation." + "\n\n" + c.help diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 3b89261915..85102196d8 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -575,10 +575,13 @@ func TestUninstall(t *testing.T) { t.Run(name, func(t *testing.T) { buf := new(bytes.Buffer) c := getInitializedCommand(t, buf) + k8s = fake.NewSimpleClientset() c.kubernetes = k8s + mock := tc.helmActionsRunner c.helmActionsRunner = mock + if tc.preProcessingFunc != nil { tc.preProcessingFunc() } diff --git a/cli/common/finalizer.go b/cli/common/finalizer.go new file mode 100644 index 0000000000..c7a8534589 --- /dev/null +++ b/cli/common/finalizer.go @@ -0,0 +1,23 @@ +package common + +import ( + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Finalizer implements the Kubernetes controller-runtime client.Patch interface +// to remove any finalizers on a resource. +// Ref: https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client@v0.13.0#Patch +type Finalizer struct{} + +// NewFinalizer returns a new Finalizer instance for patching finalizers on +// Kubernetes resources to be an empty list. +func NewFinalizer() Finalizer { return Finalizer{} } + +// Type returns the JSON Patch Type +// Ref: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment +func (f Finalizer) Type() types.PatchType { return types.JSONPatchType } + +func (f Finalizer) Data(obj client.Object) ([]byte, error) { + return nil, nil +} From 616a253b369b409f3e83b46b65879d5f87449349 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 19 Oct 2022 15:20:51 -0400 Subject: [PATCH 05/43] Patch finalizers after uninstall --- cli/cmd/uninstall/uninstall.go | 61 ++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index a2a14dcedf..e75c872ba5 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -4,9 +4,8 @@ import ( "context" "encoding/json" "fmt" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" "os" + "strings" "sync" "time" @@ -21,6 +20,10 @@ import ( "helm.sh/helm/v3/pkg/action" helmCLI "helm.sh/helm/v3/pkg/cli" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" @@ -55,9 +58,10 @@ type Command struct { helmActionsRunner helm.HelmActionsRunner // Configuration for interacting with Kubernetes. - kubernetes kubernetes.Interface - client client.Client - restClient rest.Interface + kubernetes kubernetes.Interface + dynamicKubernetes dynamic.Interface + client client.Client + restClient rest.Interface set *flag.Sets @@ -186,6 +190,13 @@ func (c *Command) Run(args []string) int { c.UI.Output("initializing Kubernetes client: %v", err, terminal.WithErrorStyle()) return 1 } + + c.dynamicKubernetes, err = dynamic.NewForConfig(restConfig) + if err != nil { + c.UI.Output("initializing Kubernetes client: %v", err, terminal.WithErrorStyle()) + return 1 + } + if c.restClient == nil { c.restClient = c.kubernetes.CoreV1().RESTClient() } @@ -366,6 +377,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin } } + // Delete any custom resources managed by Consul if releaseType == common.ReleaseTypeConsul { if err := c.deleteCustomResources(); err != nil { return err @@ -389,8 +401,12 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil } + // Patch the finalizers on any remaining custom resources so that they get deleted. if releaseType == common.ReleaseTypeConsul { - if err := c.patchCustomResources(); err != nil { + err := backoff.Retry( + func() error { return c.patchCustomResources() }, + backoff.WithMaxRetries(backoff.NewConstantBackOff(100*time.Millisecond), 1800)) + if err != nil { return err } } @@ -429,8 +445,9 @@ type crs struct { // cr is used to deserialize the JSOn definition of a single CR. type cr struct { - Kind string `json:"kind"` - Metadata struct { + ApiVersion string `json:"apiVersion"` + Kind string `json:"kind"` + Metadata struct { Name string `json:"name"` Namespace string `json:"namespace"` Uid string `json:"uid"` @@ -482,6 +499,8 @@ func (c *Command) deleteCustomResources() error { return nil } +// patchCustomResources patches the finalizers on every custom resource +// managed by Consul to be an empty list. func (c *Command) patchCustomResources() error { c.UI.Output("Patching finalizers for Consul custom resources.", terminal.WithLibraryStyle()) @@ -522,14 +541,28 @@ func (c *Command) patchCustomResources() error { } } + finalizerPatch := []byte(`[{ + "op": "replace", + "path": "/metadata/finalizers", + "value": [] + }]`) + // Patch the finalizers for each custom resource. - var target = &unstructured.Unstructured{} for _, cr := range consulCRs { - target.SetNamespace(cr.Metadata.Namespace) - target.SetName(cr.Metadata.Name) - target.SetKind(cr.Kind) + apiVersion := strings.Split(cr.ApiVersion, "/") + version := apiVersion[len(apiVersion)-1] + + target := schema.GroupVersionResource{ + Group: consulGroup, + Version: version, + Resource: strings.ToLower(cr.Kind), + } - if err := c.client.Patch(c.Ctx, target, common.NewFinalizer()); err != nil { + _, err := c.dynamicKubernetes. + Resource(target). + Namespace(cr.Metadata.Namespace). + Patch(c.Ctx, cr.Metadata.Name, types.JSONPatchType, finalizerPatch, metav1.PatchOptions{}) + if err != nil { return err } } @@ -542,7 +575,7 @@ func (c *Command) patchCustomResources() error { func crPaths(crd crd) []string { var paths []string for _, version := range crd.Spec.Versions { - paths = append(paths, fmt.Sprintf("/apis/%s/%s/%s", consulGroup, version, crd.Spec.Names.Kind)) + paths = append(paths, strings.ToLower(fmt.Sprintf("/apis/%s/%s/%s", consulGroup, version.Name, crd.Spec.Names.Kind))) } return paths } From aa9d85323373605d787c2074c3828ca01d1ebefb Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 20 Oct 2022 10:50:33 -0400 Subject: [PATCH 06/43] Add function for ignoring 404 errors --- cli/common/utils.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cli/common/utils.go b/cli/common/utils.go index b2e9714a9d..95c56a7afb 100644 --- a/cli/common/utils.go +++ b/cli/common/utils.go @@ -1,6 +1,7 @@ package common import ( + "k8s.io/apimachinery/pkg/api/errors" "os" "strings" ) @@ -81,3 +82,12 @@ func IsValidLabel(label string) bool { return true } + +// IgnoreNotFoundError is a convenience function which takes an error and will +// return it unless it represents a NotFound, 404 error. +func IgnoreNotFoundError(err error) error { + if statusError, ok := err.(*errors.StatusError); ok && statusError.ErrStatus.Code == 404 { + return nil + } + return err +} From 90ebac7088fcc1a8a6892b8ad381c8b247a1a926 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 20 Oct 2022 10:50:48 -0400 Subject: [PATCH 07/43] Change to using apiextensions lib --- cli/cmd/uninstall/uninstall.go | 305 ++++++++++++---------------- cli/cmd/uninstall/uninstall_test.go | 47 ++++- 2 files changed, 168 insertions(+), 184 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index e75c872ba5..738ab1ec2a 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -1,8 +1,6 @@ package uninstall import ( - "context" - "encoding/json" "fmt" "os" "strings" @@ -19,14 +17,13 @@ import ( "golang.org/x/text/language" "helm.sh/helm/v3/pkg/action" helmCLI "helm.sh/helm/v3/pkg/cli" + apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" ) const ( @@ -48,7 +45,6 @@ const ( flagContext = "context" flagKubeconfig = "kubeconfig" - crdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" consulGroup = "consul.hashicorp.com" ) @@ -58,10 +54,9 @@ type Command struct { helmActionsRunner helm.HelmActionsRunner // Configuration for interacting with Kubernetes. - kubernetes kubernetes.Interface - dynamicKubernetes dynamic.Interface - client client.Client - restClient rest.Interface + kubernetes kubernetes.Interface + dynamic dynamic.Interface + apiext apiext.Interface set *flag.Sets @@ -176,36 +171,8 @@ func (c *Command) Run(args []string) int { settings.KubeContext = c.flagKubeContext } - // Set up the kubernetes client to use for non Helm SDK calls to the Kubernetes API - // The Helm SDK will use settings.RESTClientGetter for its calls as well, so this will - // use a consistent method to target the right cluster for both Helm SDK and non Helm SDK calls. - if c.kubernetes == nil { - restConfig, err := settings.RESTClientGetter().ToRESTConfig() - if err != nil { - c.UI.Output("retrieving Kubernetes auth: %v", err, terminal.WithErrorStyle()) - return 1 - } - c.kubernetes, err = kubernetes.NewForConfig(restConfig) - if err != nil { - c.UI.Output("initializing Kubernetes client: %v", err, terminal.WithErrorStyle()) - return 1 - } - - c.dynamicKubernetes, err = dynamic.NewForConfig(restConfig) - if err != nil { - c.UI.Output("initializing Kubernetes client: %v", err, terminal.WithErrorStyle()) - return 1 - } - - if c.restClient == nil { - c.restClient = c.kubernetes.CoreV1().RESTClient() - } - if c.client == nil { - if c.client, err = client.New(restConfig, client.Options{}); err != nil { - c.UI.Output("error creating Kubernetes client %v", err, terminal.WithErrorStyle()) - return 1 - } - } + if err := c.initKubernetes(settings); err != nil { + c.UI.Output("Could not initialize Kubernetes client: %v", err, terminal.WithErrorStyle()) } // Setup logger to stream Helm library logs. @@ -353,6 +320,36 @@ func (c *Command) Run(args []string) int { return 0 } +// initKubernetes sets up the kubernetes client to use for non Helm SDK calls to the Kubernetes API +// The Helm SDK will use settings.RESTClientGetter for its calls as well, so this will +// use a consistent method to target the right cluster for both Helm SDK and non Helm SDK calls. +func (c *Command) initKubernetes(settings *helmCLI.EnvSettings) error { + restConfig, err := settings.RESTClientGetter().ToRESTConfig() + if err != nil { + return err + } + + if c.kubernetes == nil { + if c.kubernetes, err = kubernetes.NewForConfig(restConfig); err != nil { + return err + } + } + + if c.dynamic == nil { + if c.dynamic, err = dynamic.NewForConfig(restConfig); err != nil { + return err + } + } + + if c.apiext == nil { + if c.apiext, err = apiext.NewForConfig(restConfig); err != nil { + return err + } + } + + return nil +} + func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType string, settings *helmCLI.EnvSettings, uiLogger action.DebugLog, actionConfig *action.Configuration) error { c.UI.Output(fmt.Sprintf("Existing %s installation found.", releaseType), terminal.WithSuccessStyle()) @@ -379,7 +376,38 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // Delete any custom resources managed by Consul if releaseType == common.ReleaseTypeConsul { - if err := c.deleteCustomResources(); err != nil { + // TODO actually understand the backoff retry func + err := backoff.Retry(func() error { + crs, err := c.fetchCustomResources() + if err != nil { + return err + } + + err = c.deleteCustomResources(crs) + if err != nil { + return err + } + + return nil + }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) + if err != nil { + return err + } + + err = backoff.Retry(func() error { + crs, err := c.fetchCustomResources() + if err != nil { + return err + } + + err = c.patchCustomResources(crs) + if err != nil { + return err + } + + return nil + }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) + if err != nil { return err } } @@ -401,146 +429,73 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil } - // Patch the finalizers on any remaining custom resources so that they get deleted. - if releaseType == common.ReleaseTypeConsul { - err := backoff.Retry( - func() error { return c.patchCustomResources() }, - backoff.WithMaxRetries(backoff.NewConstantBackOff(100*time.Millisecond), 1800)) - if err != nil { - return err - } - } - c.UI.Output(fmt.Sprintf("Successfully uninstalled %s Helm release.", releaseType), terminal.WithSuccessStyle()) return nil } -// crds is used to deserialize JSON returned from the -// `/apis/apiextensions.k8s.io/v1/customresourcedefinitions` endpoint. -type crds struct { - Items []crd `json:"items"` -} - -// crd is used to deserialize the JSON definition of a single CRD. -type crd struct { - Metadata struct { - Name string `json:"name"` - } `json:"metadata"` - Spec struct { - Group string `json:"group"` - Names struct { - Kind string `json:"kind"` - } `json:"names"` - Versions []struct { - Name string `json:"name"` - } `json:"versions"` - } `json:"spec"` -} - -// crs is used to deserialize JSON returned from the -// `/apis/consul.hashicorp.com//` endpoint. -type crs struct { - Items []cr `json:"items"` -} - -// cr is used to deserialize the JSOn definition of a single CR. -type cr struct { - ApiVersion string `json:"apiVersion"` - Kind string `json:"kind"` - Metadata struct { - Name string `json:"name"` - Namespace string `json:"namespace"` - Uid string `json:"uid"` - } `json:"metadata"` -} - -// deleteCustomResources gets a list of all custom resource definitions managed -// by Consul. It then iterates over all custom resources matching these -// definitions and deletes them. A timeout is attached to each deletion in order -// to circumvent any deadlock issues which may arise. -func (c *Command) deleteCustomResources() error { - c.UI.Output("Deleting any Consul custom resources that may exist.", terminal.WithLibraryStyle()) - - raw, err := c.restClient.Get().AbsPath(crdPath).DoRaw(c.Ctx) - if err != nil { - return err - } - var crds crds - if err := json.Unmarshal(raw, &crds); err != nil { - return err - } - - namespaces, err := c.kubernetes.CoreV1().Namespaces().List(c.Ctx, metav1.ListOptions{}) +// fetchCustomResources gets a list of all custom resources deployed in the +// cluster that are managed by Consul. +func (c *Command) fetchCustomResources() ([]unstructured.Unstructured, error) { + crds, err := c.apiext.ApiextensionsV1().CustomResourceDefinitions().List(c.Ctx, metav1.ListOptions{ + LabelSelector: "app=consul", + }) if err != nil { - return err + return nil, err } + var crs []unstructured.Unstructured for _, crd := range crds.Items { - if crd.Spec.Group == "consul.hashicorp.com" { - for _, version := range crd.Spec.Versions { - for _, namespace := range namespaces.Items { - ctx, _ := context.WithTimeout(c.Ctx, time.Minute) - - cr := &unstructured.Unstructured{} - cr.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "consul.hashicorp.com", - Kind: crd.Spec.Names.Kind, - Version: version.Name, - }) - err = c.client.DeleteAllOf(ctx, cr, client.InNamespace(namespace.Name)) - if err != nil { - return err - } - } + for _, version := range crd.Spec.Versions { + target := schema.GroupVersionResource{ + Group: crd.Spec.Group, + Version: version.Name, + Resource: crd.Spec.Names.Plural, + } + + crList, err := c.dynamic.Resource(target).List(c.Ctx, metav1.ListOptions{}) + if common.IgnoreNotFoundError(err) != nil { + return nil, err + } + if crList != nil { + crs = append(crs, crList.Items...) } } } - return nil + return crs, nil } -// patchCustomResources patches the finalizers on every custom resource -// managed by Consul to be an empty list. -func (c *Command) patchCustomResources() error { - c.UI.Output("Patching finalizers for Consul custom resources.", terminal.WithLibraryStyle()) - - // Get all custom resource definitions in the Kubernetes cluster. - raw, err := c.restClient.Get().AbsPath(crdPath).DoRaw(c.Ctx) - if err != nil { - return nil - } - var allCRDs crds - if err := json.Unmarshal(raw, &allCRDs); err != nil { - return err - } +// deleteCustomResources takes a list of unstructured custom resources and +// sends a request to each one to be deleted. +func (c *Command) deleteCustomResources(crs []unstructured.Unstructured) error { + for _, cr := range crs { + apiVersion := strings.Split(cr.GetAPIVersion(), "/") + group, version := apiVersion[0], apiVersion[1] + if group == "" || version == "" { + return fmt.Errorf("malformed api version: %s", apiVersion) + } - // Filter only to CRDs managed by Consul. - var consulCRDs crds - for _, crd := range allCRDs.Items { - if crd.Spec.Group == consulGroup { - consulCRDs.Items = append(consulCRDs.Items, crd) + target := schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: strings.ToLower(cr.GetKind()), } - } - if len(consulCRDs.Items) == 0 { - return nil - } - // Get all custom resources for each custom resource definition. - var consulCRs []cr - for _, crd := range consulCRDs.Items { - for _, path := range crPaths(crd) { - raw, err := c.restClient.Get().AbsPath(path).DoRaw(c.Ctx) - if err != nil { - return err - } - var crs crs - if err := json.Unmarshal(raw, &crs); err != nil { - return err - } - consulCRs = append(consulCRs, crs.Items...) + err := c.dynamic. + Resource(target). + Namespace(cr.GetNamespace()). + Delete(c.Ctx, cr.GetName(), metav1.DeleteOptions{}) + if common.IgnoreNotFoundError(err) != nil { + return err } } + return nil +} + +// patchCustomResources takes a list of unstructured custom resources and +// sends a request to each one to patch its finalizers to an empty list. +func (c *Command) patchCustomResources(crs []unstructured.Unstructured) error { finalizerPatch := []byte(`[{ "op": "replace", "path": "/metadata/finalizers", @@ -548,38 +503,30 @@ func (c *Command) patchCustomResources() error { }]`) // Patch the finalizers for each custom resource. - for _, cr := range consulCRs { - apiVersion := strings.Split(cr.ApiVersion, "/") - version := apiVersion[len(apiVersion)-1] + for _, cr := range crs { + apiVersion := strings.Split(cr.GetAPIVersion(), "/") + group, version := apiVersion[0], apiVersion[1] + if group == "" || version == "" { + return fmt.Errorf("malformed api version: %s", apiVersion) + } target := schema.GroupVersionResource{ - Group: consulGroup, + Group: group, Version: version, - Resource: strings.ToLower(cr.Kind), + Resource: strings.ToLower(cr.GetKind()), } - _, err := c.dynamicKubernetes. + _, err := c.dynamic. Resource(target). - Namespace(cr.Metadata.Namespace). - Patch(c.Ctx, cr.Metadata.Name, types.JSONPatchType, finalizerPatch, metav1.PatchOptions{}) + Namespace(cr.GetNamespace()). + Patch(c.Ctx, cr.GetName(), types.JSONPatchType, finalizerPatch, metav1.PatchOptions{}) if err != nil { return err } } - return nil } -// crPaths returns a Kubernetes API path to the custom resources -// for each version of the custom resource definition. -func crPaths(crd crd) []string { - var paths []string - for _, version := range crd.Spec.Versions { - paths = append(paths, strings.ToLower(fmt.Sprintf("/apis/%s/%s/%s", consulGroup, version.Name, crd.Spec.Names.Kind))) - } - return paths -} - func (c *Command) Help() string { c.once.Do(c.init) s := "Usage: consul-k8s uninstall [flags]" + "\n" + "Uninstall Consul with options to delete data and resources associated with Consul installation." + "\n\n" + c.help diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 85102196d8..968d58a5dd 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -7,6 +7,7 @@ import ( "flag" "fmt" "io" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "os" "testing" @@ -23,8 +24,10 @@ import ( batchv1 "k8s.io/api/batch/v1" v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apiextFake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" + dynamicFake "k8s.io/client-go/dynamic/fake" "k8s.io/client-go/kubernetes/fake" ) @@ -414,8 +417,41 @@ func TestTaskCreateCommand_AutocompleteArgs(t *testing.T) { assert.Equal(t, complete.PredictNothing, c) } +func TestFetchCustomResources(t *testing.T) { + cases := map[string]struct { + crds apiextv1.CustomResourceDefinitionList + crs unstructured.UnstructuredList + expected unstructured.UnstructuredList + }{ + "No custom resources deployed": { + crds: apiextv1.CustomResourceDefinitionList{}, + crs: unstructured.UnstructuredList{}, + expected: unstructured.UnstructuredList{}, + }, + "Custom resources deployed": { + crds: apiextv1.CustomResourceDefinitionList{}, + crs: unstructured.UnstructuredList{}, + expected: unstructured.UnstructuredList{}, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + c := getInitializedCommand(t, nil) + c.apiext = apiextFake.NewSimpleClientset() + c.dynamic = dynamicFake.NewSimpleDynamicClient(nil) + + actual, err := c.fetchCustomResources() + require.NoError(t, err) + + for _, expected := range tc.expected.Items { + require.Contains(t, actual, expected) + } + }) + } +} + func TestUninstall(t *testing.T) { - var k8s kubernetes.Interface cases := map[string]struct { input []string messages []string @@ -469,7 +505,7 @@ func TestUninstall(t *testing.T) { expectConsulUninstalled: false, expectConsulDemoUninstalled: false, }, - "uninstall with -wipe-data flag processes other rescource and returns success": { + "uninstall with -wipe-data flag processes other resource and returns success": { input: []string{ "-wipe-data", }, @@ -576,8 +612,9 @@ func TestUninstall(t *testing.T) { buf := new(bytes.Buffer) c := getInitializedCommand(t, buf) - k8s = fake.NewSimpleClientset() - c.kubernetes = k8s + c.kubernetes = fake.NewSimpleClientset() + c.dynamic = dynamicFake.NewSimpleDynamicClient(nil) // TODO mock this with scheme + c.apiext = apiextFake.NewSimpleClientset() mock := tc.helmActionsRunner c.helmActionsRunner = mock From 68863bc610ba1d7f179828d9e91934b973b705c7 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 20 Oct 2022 14:03:00 -0400 Subject: [PATCH 08/43] Handle timeout for deletion --- cli/cmd/uninstall/uninstall.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 738ab1ec2a..8fdc001f83 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -2,6 +2,7 @@ package uninstall import ( "fmt" + "k8s.io/apimachinery/pkg/api/errors" "os" "strings" "sync" @@ -44,8 +45,6 @@ const ( flagContext = "context" flagKubeconfig = "kubeconfig" - - consulGroup = "consul.hashicorp.com" ) type Command struct { @@ -374,9 +373,9 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin } } - // Delete any custom resources managed by Consul + // Delete any custom resources managed by Consul. If they cannot be deleted, + // patch the finalizers to be empty on each one. if releaseType == common.ReleaseTypeConsul { - // TODO actually understand the backoff retry func err := backoff.Retry(func() error { crs, err := c.fetchCustomResources() if err != nil { @@ -388,13 +387,17 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return err } + crs, err = c.fetchCustomResources() + if err != nil { + return err + } + if len(crs) != 0 { + return fmt.Errorf("%d custom resources remain after deletion request. Retrying deletion", len(crs)) + } + return nil }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) - if err != nil { - return err - } - - err = backoff.Retry(func() error { + if errors.IsTimeout(err) { crs, err := c.fetchCustomResources() if err != nil { return err @@ -404,10 +407,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin if err != nil { return err } - - return nil - }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) - if err != nil { + } else if err != nil { return err } } From ca93bf42f10d84965309ec738822a0ff155790d7 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 20 Oct 2022 14:20:40 -0400 Subject: [PATCH 09/43] Remove finalizer obj (took different route) --- cli/common/finalizer.go | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 cli/common/finalizer.go diff --git a/cli/common/finalizer.go b/cli/common/finalizer.go deleted file mode 100644 index c7a8534589..0000000000 --- a/cli/common/finalizer.go +++ /dev/null @@ -1,23 +0,0 @@ -package common - -import ( - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// Finalizer implements the Kubernetes controller-runtime client.Patch interface -// to remove any finalizers on a resource. -// Ref: https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client@v0.13.0#Patch -type Finalizer struct{} - -// NewFinalizer returns a new Finalizer instance for patching finalizers on -// Kubernetes resources to be an empty list. -func NewFinalizer() Finalizer { return Finalizer{} } - -// Type returns the JSON Patch Type -// Ref: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment -func (f Finalizer) Type() types.PatchType { return types.JSONPatchType } - -func (f Finalizer) Data(obj client.Object) ([]byte, error) { - return nil, nil -} From 8f6cf15348dfa91194628b5f1a120ccf4ddfead6 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 20 Oct 2022 15:14:51 -0400 Subject: [PATCH 10/43] Add DeletionError --- cli/common/error.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 cli/common/error.go diff --git a/cli/common/error.go b/cli/common/error.go new file mode 100644 index 0000000000..7901e09b56 --- /dev/null +++ b/cli/common/error.go @@ -0,0 +1,24 @@ +package common + +// DeletionError should be used when a request was made to delete a resource +// and that request failed. +type DeletionError struct { + message string +} + +// NewDeletionError returns a new instance of DeletionError for handling +// failures in deletion requests. +func NewDeletionError(message string) *DeletionError { + return &DeletionError{message} +} + +// Error returns a string representation of the deletion error. +func (d *DeletionError) Error() string { + return d.message +} + +// IsDeletionError returns true if the error passed in is of type DeletionError. +func IsDeletionError(err error) bool { + _, ok := err.(*DeletionError) + return ok +} From bc7546d881100508535d796453bc8d42b81b8482 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 20 Oct 2022 15:59:49 -0400 Subject: [PATCH 11/43] Add some early returns --- cli/cmd/uninstall/uninstall.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 8fdc001f83..e6beb8bbb3 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -2,7 +2,6 @@ package uninstall import ( "fmt" - "k8s.io/apimachinery/pkg/api/errors" "os" "strings" "sync" @@ -392,12 +391,12 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return err } if len(crs) != 0 { - return fmt.Errorf("%d custom resources remain after deletion request. Retrying deletion", len(crs)) + return common.NewDeletionError(fmt.Sprintf("%d custom resources remain after deletion request. Retrying deletion", len(crs))) } return nil }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) - if errors.IsTimeout(err) { + if common.IsDeletionError(err) { crs, err := c.fetchCustomResources() if err != nil { return err @@ -442,6 +441,9 @@ func (c *Command) fetchCustomResources() ([]unstructured.Unstructured, error) { if err != nil { return nil, err } + if len(crds.Items) == 0 { + return nil, nil + } var crs []unstructured.Unstructured for _, crd := range crds.Items { @@ -468,6 +470,10 @@ func (c *Command) fetchCustomResources() ([]unstructured.Unstructured, error) { // deleteCustomResources takes a list of unstructured custom resources and // sends a request to each one to be deleted. func (c *Command) deleteCustomResources(crs []unstructured.Unstructured) error { + if len(crs) == 0 { + return nil + } + for _, cr := range crs { apiVersion := strings.Split(cr.GetAPIVersion(), "/") group, version := apiVersion[0], apiVersion[1] @@ -496,6 +502,10 @@ func (c *Command) deleteCustomResources(crs []unstructured.Unstructured) error { // patchCustomResources takes a list of unstructured custom resources and // sends a request to each one to patch its finalizers to an empty list. func (c *Command) patchCustomResources(crs []unstructured.Unstructured) error { + if len(crs) == 0 { + return nil + } + finalizerPatch := []byte(`[{ "op": "replace", "path": "/metadata/finalizers", From d363394bc6955ebbe6e04a2be050e25533eb5f97 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 20 Oct 2022 16:17:35 -0400 Subject: [PATCH 12/43] WIP: mocking dynamic client --- cli/cmd/uninstall/uninstall_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 968d58a5dd..5fbe33d4b0 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/kubernetes/fake" "os" "testing" @@ -27,8 +28,8 @@ import ( apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextFake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" dynamicFake "k8s.io/client-go/dynamic/fake" - "k8s.io/client-go/kubernetes/fake" ) func TestDeletePVCs(t *testing.T) { @@ -439,7 +440,7 @@ func TestFetchCustomResources(t *testing.T) { t.Run(name, func(t *testing.T) { c := getInitializedCommand(t, nil) c.apiext = apiextFake.NewSimpleClientset() - c.dynamic = dynamicFake.NewSimpleDynamicClient(nil) + c.dynamic = dynamicFake.NewSimpleDynamicClient(runtime.NewScheme()) actual, err := c.fetchCustomResources() require.NoError(t, err) @@ -613,7 +614,7 @@ func TestUninstall(t *testing.T) { c := getInitializedCommand(t, buf) c.kubernetes = fake.NewSimpleClientset() - c.dynamic = dynamicFake.NewSimpleDynamicClient(nil) // TODO mock this with scheme + c.dynamic = dynamicFake.NewSimpleDynamicClient(runtime.NewScheme()) c.apiext = apiextFake.NewSimpleClientset() mock := tc.helmActionsRunner From ac828907a13d59db792077b1f0850ffb49c15f4a Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 20 Oct 2022 22:06:07 -0400 Subject: [PATCH 13/43] Test the new functions --- cli/cmd/uninstall/uninstall.go | 2 +- cli/cmd/uninstall/uninstall_test.go | 207 ++++++++++++++++++++++++---- 2 files changed, 184 insertions(+), 25 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index e6beb8bbb3..0e3e7899a8 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -530,7 +530,7 @@ func (c *Command) patchCustomResources(crs []unstructured.Unstructured) error { Resource(target). Namespace(cr.GetNamespace()). Patch(c.Ctx, cr.GetName(), types.JSONPatchType, finalizerPatch, metav1.PatchOptions{}) - if err != nil { + if common.IgnoreNotFoundError(err) != nil { return err } } diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 5fbe33d4b0..fb031c39ff 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/kubernetes/fake" "os" "testing" @@ -419,36 +420,194 @@ func TestTaskCreateCommand_AutocompleteArgs(t *testing.T) { } func TestFetchCustomResources(t *testing.T) { - cases := map[string]struct { - crds apiextv1.CustomResourceDefinitionList - crs unstructured.UnstructuredList - expected unstructured.UnstructuredList - }{ - "No custom resources deployed": { - crds: apiextv1.CustomResourceDefinitionList{}, - crs: unstructured.UnstructuredList{}, - expected: unstructured.UnstructuredList{}, + grvToListKind := map[schema.GroupVersionResource]string{ + schema.GroupVersionResource{ + Group: "consul.hashicorp.com", + Version: "v1alpha1", + Resource: "servicedefaults", + }: "ServiceDefaultsList", + schema.GroupVersionResource{ + Group: "google.com", + Version: "v1", + Resource: "gateways", + }: "GatewaysList", + } + crds := apiextv1.CustomResourceDefinitionList{ + Items: []apiextv1.CustomResourceDefinition{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "servicedefaults.consul.hashicorp.com", + Labels: map[string]string{ + "app": "consul", + }, + }, + Spec: apiextv1.CustomResourceDefinitionSpec{ + Group: "consul.hashicorp.com", + Names: apiextv1.CustomResourceDefinitionNames{ + Plural: "servicedefaults", + ListKind: "ServiceDefaultsList", + }, + Scope: "Namespaced", + Versions: []apiextv1.CustomResourceDefinitionVersion{ + { + Name: "v1alpha1", + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "gateways.google.com", + }, + Spec: apiextv1.CustomResourceDefinitionSpec{ + Group: "google.com", + Names: apiextv1.CustomResourceDefinitionNames{ + Plural: "gateways", + ListKind: "GatewaysList", + }, + Scope: "Namespaced", + Versions: []apiextv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + }, + }, + }, + }, }, - "Custom resources deployed": { - crds: apiextv1.CustomResourceDefinitionList{}, - crs: unstructured.UnstructuredList{}, - expected: unstructured.UnstructuredList{}, + } + consulCr1 := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "consul.hashicorp.com/v1alpha1", + "kind": "ServiceDefaults", + "metadata": map[string]interface{}{ + "name": "server", + "namespace": "default", + }, + }, + } + consulCr2 := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "consul.hashicorp.com/v1alpha1", + "kind": "ServiceDefaults", + "metadata": map[string]interface{}{ + "name": "other-server", + "namespace": "other", + }, + }, + } + otherCr := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "google.com/v1", + "kind": "Gateways", + "metadata": map[string]interface{}{ + "name": "google-gateway", + "namespace": "google", + }, }, } - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - c := getInitializedCommand(t, nil) - c.apiext = apiextFake.NewSimpleClientset() - c.dynamic = dynamicFake.NewSimpleDynamicClient(runtime.NewScheme()) + c := getInitializedCommand(t, nil) + c.apiext = apiextFake.NewSimpleClientset(&crds) + c.dynamic = dynamicFake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), grvToListKind, &consulCr1, &consulCr2, &otherCr) - actual, err := c.fetchCustomResources() - require.NoError(t, err) + actual, err := c.fetchCustomResources() + require.NoError(t, err) - for _, expected := range tc.expected.Items { - require.Contains(t, actual, expected) - } - }) + require.Contains(t, actual, consulCr1) + require.Contains(t, actual, consulCr2) + require.NotContains(t, actual, otherCr) +} + +func TestDeleteCustomResources(t *testing.T) { + grvToListKind := map[schema.GroupVersionResource]string{ + schema.GroupVersionResource{ + Group: "consul.hashicorp.com", + Version: "v1alpha1", + Resource: "servicedefaults", + }: "ServiceDefaultsList", + } + consulCr1 := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "consul.hashicorp.com/v1alpha1", + "kind": "ServiceDefaults", + "metadata": map[string]interface{}{ + "name": "server", + "namespace": "default", + }, + }, + } + consulCr2 := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "consul.hashicorp.com/v1alpha1", + "kind": "ServiceDefaults", + "metadata": map[string]interface{}{ + "name": "other-server", + "namespace": "other", + }, + }, + } + + c := getInitializedCommand(t, nil) + c.apiext = apiextFake.NewSimpleClientset() + c.dynamic = dynamicFake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), grvToListKind, &consulCr1, &consulCr2) + + actual, err := c.fetchCustomResources() + require.NoError(t, err) + require.Len(t, actual, 2) + + err = c.deleteCustomResources([]unstructured.Unstructured{consulCr1, consulCr2}) + require.NoError(t, err) + + actual, err = c.fetchCustomResources() + require.NoError(t, err) + require.Len(t, actual, 0) +} + +func TestPatchCustomResources(t *testing.T) { + grvToListKind := map[schema.GroupVersionResource]string{ + schema.GroupVersionResource{ + Group: "consul.hashicorp.com", + Version: "v1alpha1", + Resource: "servicedefaults", + }: "ServiceDefaultsList", + } + consulCr1 := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "consul.hashicorp.com/v1alpha1", + "kind": "ServiceDefaults", + "metadata": map[string]interface{}{ + "name": "server", + "namespace": "default", + "finalizers": "[consul.hashicorp.com]", + }, + }, + } + consulCr2 := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "consul.hashicorp.com/v1alpha1", + "kind": "ServiceDefaults", + "metadata": map[string]interface{}{ + "name": "other-server", + "namespace": "other", + "finalizers": "[consul.hashicorp.com]", + }, + }, + } + + c := getInitializedCommand(t, nil) + c.apiext = apiextFake.NewSimpleClientset() + c.dynamic = dynamicFake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), grvToListKind, &consulCr1, &consulCr2) + + err := c.patchCustomResources([]unstructured.Unstructured{consulCr1, consulCr2}) + require.NoError(t, err) + + actual, err := c.fetchCustomResources() + require.NoError(t, err) + require.Len(t, actual, 2) + + // Finalizers for all CRs must be empty. + for _, cr := range actual { + require.Len(t, cr.GetFinalizers(), 0) } } From c2ffdf16113107e97b4ec85397f2fbe09f2a4a96 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 21 Oct 2022 15:13:09 -0400 Subject: [PATCH 14/43] Finish mocking the CRs in tests --- cli/cmd/uninstall/uninstall.go | 18 +- cli/cmd/uninstall/uninstall_test.go | 305 ++++++++++++++-------------- 2 files changed, 156 insertions(+), 167 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 0e3e7899a8..b0d6728390 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -435,17 +435,15 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // fetchCustomResources gets a list of all custom resources deployed in the // cluster that are managed by Consul. func (c *Command) fetchCustomResources() ([]unstructured.Unstructured, error) { + crs := make([]unstructured.Unstructured, 0) + crds, err := c.apiext.ApiextensionsV1().CustomResourceDefinitions().List(c.Ctx, metav1.ListOptions{ LabelSelector: "app=consul", }) if err != nil { - return nil, err - } - if len(crds.Items) == 0 { - return nil, nil + return crs, err } - var crs []unstructured.Unstructured for _, crd := range crds.Items { for _, version := range crd.Spec.Versions { target := schema.GroupVersionResource{ @@ -470,10 +468,6 @@ func (c *Command) fetchCustomResources() ([]unstructured.Unstructured, error) { // deleteCustomResources takes a list of unstructured custom resources and // sends a request to each one to be deleted. func (c *Command) deleteCustomResources(crs []unstructured.Unstructured) error { - if len(crs) == 0 { - return nil - } - for _, cr := range crs { apiVersion := strings.Split(cr.GetAPIVersion(), "/") group, version := apiVersion[0], apiVersion[1] @@ -502,17 +496,12 @@ func (c *Command) deleteCustomResources(crs []unstructured.Unstructured) error { // patchCustomResources takes a list of unstructured custom resources and // sends a request to each one to patch its finalizers to an empty list. func (c *Command) patchCustomResources(crs []unstructured.Unstructured) error { - if len(crs) == 0 { - return nil - } - finalizerPatch := []byte(`[{ "op": "replace", "path": "/metadata/finalizers", "value": [] }]`) - // Patch the finalizers for each custom resource. for _, cr := range crs { apiVersion := strings.Split(cr.GetAPIVersion(), "/") group, version := apiVersion[0], apiVersion[1] @@ -534,6 +523,7 @@ func (c *Command) patchCustomResources(crs []unstructured.Unstructured) error { return err } } + return nil } diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index fb031c39ff..aabba5f02f 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -7,8 +7,10 @@ import ( "flag" "fmt" "io" + apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes/fake" "os" "testing" @@ -33,6 +35,19 @@ import ( dynamicFake "k8s.io/client-go/dynamic/fake" ) +var ( + serviceDefaultsGRV = schema.GroupVersionResource{ + Group: "consul.hashicorp.com", + Version: "v1alpha1", + Resource: "servicedefaults", + } + nonConsulGRV = schema.GroupVersionResource{ + Group: "example.com", + Version: "v1", + Resource: "examples", + } +) + func TestDeletePVCs(t *testing.T) { c := getInitializedCommand(t, nil) c.kubernetes = fake.NewSimpleClientset() @@ -420,62 +435,7 @@ func TestTaskCreateCommand_AutocompleteArgs(t *testing.T) { } func TestFetchCustomResources(t *testing.T) { - grvToListKind := map[schema.GroupVersionResource]string{ - schema.GroupVersionResource{ - Group: "consul.hashicorp.com", - Version: "v1alpha1", - Resource: "servicedefaults", - }: "ServiceDefaultsList", - schema.GroupVersionResource{ - Group: "google.com", - Version: "v1", - Resource: "gateways", - }: "GatewaysList", - } - crds := apiextv1.CustomResourceDefinitionList{ - Items: []apiextv1.CustomResourceDefinition{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "servicedefaults.consul.hashicorp.com", - Labels: map[string]string{ - "app": "consul", - }, - }, - Spec: apiextv1.CustomResourceDefinitionSpec{ - Group: "consul.hashicorp.com", - Names: apiextv1.CustomResourceDefinitionNames{ - Plural: "servicedefaults", - ListKind: "ServiceDefaultsList", - }, - Scope: "Namespaced", - Versions: []apiextv1.CustomResourceDefinitionVersion{ - { - Name: "v1alpha1", - }, - }, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "gateways.google.com", - }, - Spec: apiextv1.CustomResourceDefinitionSpec{ - Group: "google.com", - Names: apiextv1.CustomResourceDefinitionNames{ - Plural: "gateways", - ListKind: "GatewaysList", - }, - Scope: "Namespaced", - Versions: []apiextv1.CustomResourceDefinitionVersion{ - { - Name: "v1", - }, - }, - }, - }, - }, - } - consulCr1 := unstructured.Unstructured{ + cr := unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "consul.hashicorp.com/v1alpha1", "kind": "ServiceDefaults", @@ -485,48 +445,34 @@ func TestFetchCustomResources(t *testing.T) { }, }, } - consulCr2 := unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "consul.hashicorp.com/v1alpha1", - "kind": "ServiceDefaults", - "metadata": map[string]interface{}{ - "name": "other-server", - "namespace": "other", - }, - }, - } - otherCr := unstructured.Unstructured{ + nonConsulCR := unstructured.Unstructured{ Object: map[string]interface{}{ - "apiVersion": "google.com/v1", - "kind": "Gateways", + "apiVersion": "example.com/v1", + "kind": "Example", "metadata": map[string]interface{}{ - "name": "google-gateway", - "namespace": "google", + "name": "example-resource", + "namespace": "default", }, }, } c := getInitializedCommand(t, nil) - c.apiext = apiextFake.NewSimpleClientset(&crds) - c.dynamic = dynamicFake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), grvToListKind, &consulCr1, &consulCr2, &otherCr) + c.apiext, c.dynamic = createClientsWithCrds() - actual, err := c.fetchCustomResources() + _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + require.NoError(t, err) + _, err = c.dynamic.Resource(nonConsulGRV).Namespace("default").Create(context.Background(), &nonConsulCR, metav1.CreateOptions{}) require.NoError(t, err) - require.Contains(t, actual, consulCr1) - require.Contains(t, actual, consulCr2) - require.NotContains(t, actual, otherCr) + actual, err := c.fetchCustomResources() + require.NoError(t, err) + require.Len(t, actual, 1) + require.Contains(t, actual, cr) + require.NotContains(t, actual, nonConsulCR) } func TestDeleteCustomResources(t *testing.T) { - grvToListKind := map[schema.GroupVersionResource]string{ - schema.GroupVersionResource{ - Group: "consul.hashicorp.com", - Version: "v1alpha1", - Resource: "servicedefaults", - }: "ServiceDefaultsList", - } - consulCr1 := unstructured.Unstructured{ + cr := unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "consul.hashicorp.com/v1alpha1", "kind": "ServiceDefaults", @@ -536,26 +482,18 @@ func TestDeleteCustomResources(t *testing.T) { }, }, } - consulCr2 := unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "consul.hashicorp.com/v1alpha1", - "kind": "ServiceDefaults", - "metadata": map[string]interface{}{ - "name": "other-server", - "namespace": "other", - }, - }, - } c := getInitializedCommand(t, nil) - c.apiext = apiextFake.NewSimpleClientset() - c.dynamic = dynamicFake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), grvToListKind, &consulCr1, &consulCr2) + c.apiext, c.dynamic = createClientsWithCrds() + + _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + require.NoError(t, err) actual, err := c.fetchCustomResources() require.NoError(t, err) - require.Len(t, actual, 2) + require.Len(t, actual, 1) - err = c.deleteCustomResources([]unstructured.Unstructured{consulCr1, consulCr2}) + err = c.deleteCustomResources([]unstructured.Unstructured{cr}) require.NoError(t, err) actual, err = c.fetchCustomResources() @@ -564,46 +502,30 @@ func TestDeleteCustomResources(t *testing.T) { } func TestPatchCustomResources(t *testing.T) { - grvToListKind := map[schema.GroupVersionResource]string{ - schema.GroupVersionResource{ - Group: "consul.hashicorp.com", - Version: "v1alpha1", - Resource: "servicedefaults", - }: "ServiceDefaultsList", - } - consulCr1 := unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "consul.hashicorp.com/v1alpha1", - "kind": "ServiceDefaults", - "metadata": map[string]interface{}{ - "name": "server", - "namespace": "default", - "finalizers": "[consul.hashicorp.com]", - }, - }, - } - consulCr2 := unstructured.Unstructured{ + cr := unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "consul.hashicorp.com/v1alpha1", "kind": "ServiceDefaults", "metadata": map[string]interface{}{ - "name": "other-server", - "namespace": "other", - "finalizers": "[consul.hashicorp.com]", + "name": "server", + "namespace": "default", }, }, } + cr.SetFinalizers([]string{"consul.hashicorp.com"}) c := getInitializedCommand(t, nil) - c.apiext = apiextFake.NewSimpleClientset() - c.dynamic = dynamicFake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), grvToListKind, &consulCr1, &consulCr2) + c.apiext, c.dynamic = createClientsWithCrds() + + _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + require.NoError(t, err) - err := c.patchCustomResources([]unstructured.Unstructured{consulCr1, consulCr2}) + err = c.patchCustomResources([]unstructured.Unstructured{cr}) require.NoError(t, err) actual, err := c.fetchCustomResources() require.NoError(t, err) - require.Len(t, actual, 2) + require.Len(t, actual, 1) // Finalizers for all CRs must be empty. for _, cr := range actual { @@ -767,34 +689,111 @@ func TestUninstall(t *testing.T) { expectConsulDemoUninstalled: false, }, } + + cr := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "consul.hashicorp.com/v1alpha1", + "kind": "ServiceDefaults", + "metadata": map[string]interface{}{ + "name": "server", + "namespace": "default", + }, + }, + } + cr.SetFinalizers([]string{"consul.hashicorp.com"}) + for name, tc := range cases { - t.Run(name, func(t *testing.T) { - buf := new(bytes.Buffer) - c := getInitializedCommand(t, buf) - - c.kubernetes = fake.NewSimpleClientset() - c.dynamic = dynamicFake.NewSimpleDynamicClient(runtime.NewScheme()) - c.apiext = apiextFake.NewSimpleClientset() - - mock := tc.helmActionsRunner - c.helmActionsRunner = mock - - if tc.preProcessingFunc != nil { - tc.preProcessingFunc() - } - input := append([]string{ - "--auto-approve", - }, tc.input...) - returnCode := c.Run(input) - require.Equal(t, tc.expectedReturnCode, returnCode) - require.Equal(t, tc.expectCheckedForConsulInstallations, mock.CheckedForConsulInstallations) - require.Equal(t, tc.expectCheckedForConsulDemoInstallations, mock.CheckedForConsulDemoInstallations) - require.Equal(t, tc.expectConsulUninstalled, mock.ConsulUninstalled) - require.Equal(t, tc.expectConsulDemoUninstalled, mock.ConsulDemoUninstalled) - output := buf.String() - for _, msg := range tc.messages { - require.Contains(t, output, msg) - } - }) + for _, withController := range []bool{false, true} { + t.Run(name, func(t *testing.T) { + buf := new(bytes.Buffer) + c := getInitializedCommand(t, buf) + + c.kubernetes = fake.NewSimpleClientset() + + if withController { + c.apiext, c.dynamic = createClientsWithCrds() + _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + require.NoError(t, err) + } else { + c.dynamic = dynamicFake.NewSimpleDynamicClient(runtime.NewScheme()) + c.apiext = apiextFake.NewSimpleClientset() + } + + mock := tc.helmActionsRunner + c.helmActionsRunner = mock + + if tc.preProcessingFunc != nil { + tc.preProcessingFunc() + } + input := append([]string{ + "--auto-approve", + }, tc.input...) + returnCode := c.Run(input) + require.Equal(t, tc.expectedReturnCode, returnCode) + require.Equal(t, tc.expectCheckedForConsulInstallations, mock.CheckedForConsulInstallations) + require.Equal(t, tc.expectCheckedForConsulDemoInstallations, mock.CheckedForConsulDemoInstallations) + require.Equal(t, tc.expectConsulUninstalled, mock.ConsulUninstalled) + require.Equal(t, tc.expectConsulDemoUninstalled, mock.ConsulDemoUninstalled) + output := buf.String() + for _, msg := range tc.messages { + require.Contains(t, output, msg) + } + + if withController { + + } + }) + } + } +} + +func createClientsWithCrds() (apiext.Interface, dynamic.Interface) { + grvToListKind := map[schema.GroupVersionResource]string{ + serviceDefaultsGRV: "ServiceDefaultsList", + nonConsulGRV: "ExamplesList", + } + crds := apiextv1.CustomResourceDefinitionList{ + Items: []apiextv1.CustomResourceDefinition{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "servicedefaults.consul.hashicorp.com", + Labels: map[string]string{ + "app": "consul", + }, + }, + Spec: apiextv1.CustomResourceDefinitionSpec{ + Group: "consul.hashicorp.com", + Names: apiextv1.CustomResourceDefinitionNames{ + Plural: "servicedefaults", + ListKind: "ServiceDefaultsList", + }, + Scope: "Namespaced", + Versions: []apiextv1.CustomResourceDefinitionVersion{ + { + Name: "v1alpha1", + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "examples.example.com", + }, + Spec: apiextv1.CustomResourceDefinitionSpec{ + Group: "example.com", + Names: apiextv1.CustomResourceDefinitionNames{ + Plural: "examples", + ListKind: "ExamplesList", + }, + Scope: "Namespaced", + Versions: []apiextv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + }, + }, + }, + }, + }, } + return apiextFake.NewSimpleClientset(&crds), dynamicFake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), grvToListKind) } From 573ceccee82f6177bf8673ea459586827149a97d Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 21 Oct 2022 15:48:53 -0400 Subject: [PATCH 15/43] Polish tests --- cli/cmd/uninstall/uninstall.go | 13 +++++++------ cli/cmd/uninstall/uninstall_test.go | 15 +++++---------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index b0d6728390..cad0972ab1 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -318,7 +318,7 @@ func (c *Command) Run(args []string) int { return 0 } -// initKubernetes sets up the kubernetes client to use for non Helm SDK calls to the Kubernetes API +// initKubernetes sets up the kubernetes clients to use for non Helm SDK calls to the Kubernetes API // The Helm SDK will use settings.RESTClientGetter for its calls as well, so this will // use a consistent method to target the right cluster for both Helm SDK and non Helm SDK calls. func (c *Command) initKubernetes(settings *helmCLI.EnvSettings) error { @@ -380,9 +380,11 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin if err != nil { return err } + if len(crs) == 0 { + return nil + } - err = c.deleteCustomResources(crs) - if err != nil { + if err = c.deleteCustomResources(crs); err != nil { return err } @@ -402,8 +404,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return err } - err = c.patchCustomResources(crs) - if err != nil { + if err = c.patchCustomResources(crs); err != nil { return err } } else if err != nil { @@ -453,7 +454,7 @@ func (c *Command) fetchCustomResources() ([]unstructured.Unstructured, error) { } crList, err := c.dynamic.Resource(target).List(c.Ctx, metav1.ListOptions{}) - if common.IgnoreNotFoundError(err) != nil { + if err != nil { return nil, err } if crList != nil { diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index aabba5f02f..b288919759 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -526,11 +526,7 @@ func TestPatchCustomResources(t *testing.T) { actual, err := c.fetchCustomResources() require.NoError(t, err) require.Len(t, actual, 1) - - // Finalizers for all CRs must be empty. - for _, cr := range actual { - require.Len(t, cr.GetFinalizers(), 0) - } + require.Len(t, actual[0].GetFinalizers(), 0) } func TestUninstall(t *testing.T) { @@ -710,13 +706,10 @@ func TestUninstall(t *testing.T) { c.kubernetes = fake.NewSimpleClientset() + c.apiext, c.dynamic = createClientsWithCrds() if withController { - c.apiext, c.dynamic = createClientsWithCrds() _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) require.NoError(t, err) - } else { - c.dynamic = dynamicFake.NewSimpleDynamicClient(runtime.NewScheme()) - c.apiext = apiextFake.NewSimpleClientset() } mock := tc.helmActionsRunner @@ -740,7 +733,9 @@ func TestUninstall(t *testing.T) { } if withController { - + crs, err := c.fetchCustomResources() + require.NoError(t, err) + require.Len(t, crs, 0) } }) } From b5922e3a8d0ad08cdac2cec22ceb0beae0ab5367 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 21 Oct 2022 15:53:18 -0400 Subject: [PATCH 16/43] Add CR deletion to full uninstall test --- cli/cmd/uninstall/uninstall_test.go | 128 +++++++++++++++++++--------- 1 file changed, 88 insertions(+), 40 deletions(-) diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index b288919759..743a3bb1e8 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -535,6 +535,7 @@ func TestUninstall(t *testing.T) { messages []string helmActionsRunner *helm.MockActionRunner preProcessingFunc func() + withController bool expectedReturnCode int expectCheckedForConsulInstallations bool expectCheckedForConsulDemoInstallations bool @@ -563,6 +564,29 @@ func TestUninstall(t *testing.T) { expectConsulUninstalled: true, expectConsulDemoUninstalled: false, }, + "uninstall when consul installation exists returns success with controller deployed": { + input: []string{}, + messages: []string{ + "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n", + "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", + }, + helmActionsRunner: &helm.MockActionRunner{ + CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { + if options.ReleaseName == "consul" { + return true, "consul", "consul", nil + } else { + return false, "", "", nil + } + }, + }, + withController: true, + expectedReturnCode: 0, + expectCheckedForConsulInstallations: true, + expectCheckedForConsulDemoInstallations: true, + expectConsulUninstalled: true, + expectConsulDemoUninstalled: false, + }, "uninstall when consul installation does not exist returns error": { input: []string{}, messages: []string{ @@ -608,6 +632,32 @@ func TestUninstall(t *testing.T) { expectConsulUninstalled: true, expectConsulDemoUninstalled: false, }, + "uninstall with -wipe-data flag processes other resource and returns success with controller deployed": { + input: []string{ + "-wipe-data", + }, + messages: []string{ + "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n No existing Consul demo application installation found.\n", + "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n ✓ Successfully uninstalled Consul Helm release.\n", + "\n==> Other Consul Resources\n Deleting data for installation: \n Name: consul\n Namespace consul\n ✓ No PVCs found.\n ✓ No Consul secrets found.\n ✓ No Consul service accounts found.\n ✓ No Consul roles found.\n ✓ No Consul rolebindings found.\n ✓ No Consul jobs found.\n ✓ No Consul cluster roles found.\n ✓ No Consul cluster role bindings found.\n", + }, + helmActionsRunner: &helm.MockActionRunner{ + CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { + if options.ReleaseName == "consul" { + return true, "consul", "consul", nil + } else { + return false, "", "", nil + } + }, + }, + withController: true, + expectedReturnCode: 0, + expectCheckedForConsulInstallations: true, + expectCheckedForConsulDemoInstallations: true, + expectConsulUninstalled: true, + expectConsulDemoUninstalled: false, + }, "uninstall when both consul and consul demo installations exist returns success": { input: []string{}, messages: []string{ @@ -699,46 +749,44 @@ func TestUninstall(t *testing.T) { cr.SetFinalizers([]string{"consul.hashicorp.com"}) for name, tc := range cases { - for _, withController := range []bool{false, true} { - t.Run(name, func(t *testing.T) { - buf := new(bytes.Buffer) - c := getInitializedCommand(t, buf) - - c.kubernetes = fake.NewSimpleClientset() - - c.apiext, c.dynamic = createClientsWithCrds() - if withController { - _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) - require.NoError(t, err) - } - - mock := tc.helmActionsRunner - c.helmActionsRunner = mock - - if tc.preProcessingFunc != nil { - tc.preProcessingFunc() - } - input := append([]string{ - "--auto-approve", - }, tc.input...) - returnCode := c.Run(input) - require.Equal(t, tc.expectedReturnCode, returnCode) - require.Equal(t, tc.expectCheckedForConsulInstallations, mock.CheckedForConsulInstallations) - require.Equal(t, tc.expectCheckedForConsulDemoInstallations, mock.CheckedForConsulDemoInstallations) - require.Equal(t, tc.expectConsulUninstalled, mock.ConsulUninstalled) - require.Equal(t, tc.expectConsulDemoUninstalled, mock.ConsulDemoUninstalled) - output := buf.String() - for _, msg := range tc.messages { - require.Contains(t, output, msg) - } - - if withController { - crs, err := c.fetchCustomResources() - require.NoError(t, err) - require.Len(t, crs, 0) - } - }) - } + t.Run(name, func(t *testing.T) { + buf := new(bytes.Buffer) + c := getInitializedCommand(t, buf) + + c.kubernetes = fake.NewSimpleClientset() + + c.apiext, c.dynamic = createClientsWithCrds() + if tc.withController { + _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + require.NoError(t, err) + } + + mock := tc.helmActionsRunner + c.helmActionsRunner = mock + + if tc.preProcessingFunc != nil { + tc.preProcessingFunc() + } + input := append([]string{ + "--auto-approve", + }, tc.input...) + returnCode := c.Run(input) + require.Equal(t, tc.expectedReturnCode, returnCode) + require.Equal(t, tc.expectCheckedForConsulInstallations, mock.CheckedForConsulInstallations) + require.Equal(t, tc.expectCheckedForConsulDemoInstallations, mock.CheckedForConsulDemoInstallations) + require.Equal(t, tc.expectConsulUninstalled, mock.ConsulUninstalled) + require.Equal(t, tc.expectConsulDemoUninstalled, mock.ConsulDemoUninstalled) + output := buf.String() + for _, msg := range tc.messages { + require.Contains(t, output, msg) + } + + if tc.withController { + crs, err := c.fetchCustomResources() + require.NoError(t, err) + require.Len(t, crs, 0) + } + }) } } From 273e63b270b32aa67175bbc168aadff4c6859536 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 21 Oct 2022 15:53:44 -0400 Subject: [PATCH 17/43] go mod tidy --- cli/go.mod | 6 +++--- cli/go.sum | 17 +++++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/cli/go.mod b/cli/go.mod index 76d685a257..2017bd30cc 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -19,11 +19,11 @@ require ( golang.org/x/text v0.3.7 helm.sh/helm/v3 v3.9.4 k8s.io/api v0.25.0 + k8s.io/apiextensions-apiserver v0.25.0 k8s.io/apimachinery v0.25.0 k8s.io/cli-runtime v0.24.3 k8s.io/client-go v0.25.0 k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed - sigs.k8s.io/controller-runtime v0.13.0 sigs.k8s.io/yaml v1.3.0 ) @@ -63,8 +63,8 @@ require ( github.com/docker/go-units v0.4.0 // indirect github.com/emicklei/go-restful/v3 v3.8.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-gorp/gorp/v3 v3.0.2 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -123,6 +123,7 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo v1.16.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect @@ -160,7 +161,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.25.0 // indirect k8s.io/apiserver v0.25.0 // indirect k8s.io/component-base v0.25.0 // indirect k8s.io/klog/v2 v2.70.1 // indirect diff --git a/cli/go.sum b/cli/go.sum index c8affbd2ae..861f2d8dc9 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -207,8 +207,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= @@ -222,6 +220,7 @@ github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -246,7 +245,6 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= -github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= 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.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -345,6 +343,7 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -529,7 +528,6 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= @@ -677,6 +675,7 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= @@ -685,6 +684,7 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -858,14 +858,11 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20200707032745-474f21a9602d h1:uFqwFYlX7d5ZSp+IqhXxct0SybXrTzEBDvb2CkEhPBs= go.starlark.net v0.0.0-20200707032745-474f21a9602d/go.mod h1:f0znQkUKRrkk36XxWbGjMqQM8wGv/xHBVE2qc3B5oFU= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -1064,6 +1061,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1090,6 +1088,7 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1169,6 +1168,7 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= @@ -1183,7 +1183,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1418,8 +1417,6 @@ oras.land/oras-go v1.2.0/go.mod h1:pFNs7oHp2dYsYMSS82HaX5l4mpnGO7hbpPN6EWH2ltc= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= -sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= From d200b8431b682249ce9191eeeecd8c507f38ff24 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 21 Oct 2022 15:55:38 -0400 Subject: [PATCH 18/43] Add output to notify user of deletion/patching process --- cli/cmd/uninstall/uninstall.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index cad0972ab1..17be99ada0 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -375,6 +375,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // Delete any custom resources managed by Consul. If they cannot be deleted, // patch the finalizers to be empty on each one. if releaseType == common.ReleaseTypeConsul { + c.UI.Output("Deleting custom resources managed by Consul.", terminal.WithLibraryStyle()) err := backoff.Retry(func() error { crs, err := c.fetchCustomResources() if err != nil { @@ -399,6 +400,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) if common.IsDeletionError(err) { + c.UI.Output("Patching finalizers on custom resources managed by Consul.", terminal.WithLibraryStyle()) crs, err := c.fetchCustomResources() if err != nil { return err From 26879412c57dfbf2f3268c2afc067c04b914686b Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Sat, 22 Oct 2022 11:33:12 -0400 Subject: [PATCH 19/43] Polish output text --- cli/cmd/install/install.go | 2 +- cli/cmd/uninstall/uninstall.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/cmd/install/install.go b/cli/cmd/install/install.go index 49b5fe5a7f..7b5d5bb31c 100644 --- a/cli/cmd/install/install.go +++ b/cli/cmd/install/install.go @@ -401,7 +401,7 @@ func (c *Command) installConsul(valuesYaml []byte, vals map[string]interface{}, if len(vals) == 0 { c.UI.Output("\nNo overrides provided, using the default Helm values.", terminal.WithInfoStyle()) } else { - c.UI.Output("\nHelm value overrides\n-------------------\n"+string(valuesYaml), terminal.WithInfoStyle()) + c.UI.Output("\nHelm value overrides\n--------------------\n"+string(valuesYaml), terminal.WithInfoStyle()) } // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 17be99ada0..3f2623d370 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -375,7 +375,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // Delete any custom resources managed by Consul. If they cannot be deleted, // patch the finalizers to be empty on each one. if releaseType == common.ReleaseTypeConsul { - c.UI.Output("Deleting custom resources managed by Consul.", terminal.WithLibraryStyle()) + c.UI.Output("Deleting custom resources managed by Consul", terminal.WithLibraryStyle()) err := backoff.Retry(func() error { crs, err := c.fetchCustomResources() if err != nil { @@ -400,7 +400,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) if common.IsDeletionError(err) { - c.UI.Output("Patching finalizers on custom resources managed by Consul.", terminal.WithLibraryStyle()) + c.UI.Output("Patching finalizers on custom resources managed by Consul", terminal.WithLibraryStyle()) crs, err := c.fetchCustomResources() if err != nil { return err From 56ba32347c45f2547839da86810e2dc5969b3f31 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 26 Oct 2022 09:35:53 -0400 Subject: [PATCH 20/43] Add mapping of kind to resource name --- cli/cmd/uninstall/uninstall.go | 56 ++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 3f2623d370..91b50af82c 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -12,11 +12,13 @@ import ( "github.com/hashicorp/consul-k8s/cli/common/flag" "github.com/hashicorp/consul-k8s/cli/common/terminal" "github.com/hashicorp/consul-k8s/cli/helm" + "github.com/posener/complete" "golang.org/x/text/cases" "golang.org/x/text/language" "helm.sh/helm/v3/pkg/action" helmCLI "helm.sh/helm/v3/pkg/cli" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -376,8 +378,13 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // patch the finalizers to be empty on each one. if releaseType == common.ReleaseTypeConsul { c.UI.Output("Deleting custom resources managed by Consul", terminal.WithLibraryStyle()) - err := backoff.Retry(func() error { - crs, err := c.fetchCustomResources() + crds, err := c.fetchCustomResourceDefinitions() + if err != nil { + return fmt.Errorf("unable to fetch Custom Resource Definitions for Consul deployment: %v", err) + } + kindToResource := mapCRKindToResourceName(crds) + err = backoff.Retry(func() error { + crs, err := c.fetchCustomResources(crds) if err != nil { return err } @@ -385,11 +392,11 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil } - if err = c.deleteCustomResources(crs); err != nil { + if err = c.deleteCustomResources(crs, kindToResource); err != nil { return err } - crs, err = c.fetchCustomResources() + crs, err = c.fetchCustomResources(crds) if err != nil { return err } @@ -401,12 +408,12 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) if common.IsDeletionError(err) { c.UI.Output("Patching finalizers on custom resources managed by Consul", terminal.WithLibraryStyle()) - crs, err := c.fetchCustomResources() + crs, err := c.fetchCustomResources(crds) if err != nil { return err } - if err = c.patchCustomResources(crs); err != nil { + if err = c.patchCustomResources(crs, kindToResource); err != nil { return err } } else if err != nil { @@ -435,18 +442,17 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil } -// fetchCustomResources gets a list of all custom resources deployed in the -// cluster that are managed by Consul. -func (c *Command) fetchCustomResources() ([]unstructured.Unstructured, error) { - crs := make([]unstructured.Unstructured, 0) - - crds, err := c.apiext.ApiextensionsV1().CustomResourceDefinitions().List(c.Ctx, metav1.ListOptions{ +// fetchCustomResourceDefinitions fetches all Custom Resource Definitions managed by Consul. +func (c *Command) fetchCustomResourceDefinitions() (*apiextv1.CustomResourceDefinitionList, error) { + return c.apiext.ApiextensionsV1().CustomResourceDefinitions().List(c.Ctx, metav1.ListOptions{ LabelSelector: "app=consul", }) - if err != nil { - return crs, err - } +} +// fetchCustomResources gets a list of all custom resources deployed in the +// cluster that are managed by Consul. +func (c *Command) fetchCustomResources(crds *apiextv1.CustomResourceDefinitionList) ([]unstructured.Unstructured, error) { + crs := make([]unstructured.Unstructured, 0) for _, crd := range crds.Items { for _, version := range crd.Spec.Versions { target := schema.GroupVersionResource{ @@ -470,7 +476,7 @@ func (c *Command) fetchCustomResources() ([]unstructured.Unstructured, error) { // deleteCustomResources takes a list of unstructured custom resources and // sends a request to each one to be deleted. -func (c *Command) deleteCustomResources(crs []unstructured.Unstructured) error { +func (c *Command) deleteCustomResources(crs []unstructured.Unstructured, kindToResource map[string]string) error { for _, cr := range crs { apiVersion := strings.Split(cr.GetAPIVersion(), "/") group, version := apiVersion[0], apiVersion[1] @@ -481,7 +487,7 @@ func (c *Command) deleteCustomResources(crs []unstructured.Unstructured) error { target := schema.GroupVersionResource{ Group: group, Version: version, - Resource: strings.ToLower(cr.GetKind()), + Resource: kindToResource[cr.GetKind()], } err := c.dynamic. @@ -498,7 +504,7 @@ func (c *Command) deleteCustomResources(crs []unstructured.Unstructured) error { // patchCustomResources takes a list of unstructured custom resources and // sends a request to each one to patch its finalizers to an empty list. -func (c *Command) patchCustomResources(crs []unstructured.Unstructured) error { +func (c *Command) patchCustomResources(crs []unstructured.Unstructured, kindToResource map[string]string) error { finalizerPatch := []byte(`[{ "op": "replace", "path": "/metadata/finalizers", @@ -515,7 +521,7 @@ func (c *Command) patchCustomResources(crs []unstructured.Unstructured) error { target := schema.GroupVersionResource{ Group: group, Version: version, - Resource: strings.ToLower(cr.GetKind()), + Resource: kindToResource[cr.GetKind()], } _, err := c.dynamic. @@ -814,3 +820,15 @@ func (c *Command) deleteClusterRoleBindings(foundReleaseName string) error { } return nil } + +// mapCRKindToResourceName takes the list of custom resource definitions and +// creates a mapping from the "kind" of the CRD to its "resource" name. +// This is needed for the dynamic API which finds custom resources by their +// lowercase, plural resource name. (e.g. "ingressgateways" for "IngressGateway" kind). +func mapCRKindToResourceName(crds *apiextv1.CustomResourceDefinitionList) map[string]string { + kindToResourceName := make(map[string]string) + for _, crd := range crds.Items { + kindToResourceName[crd.Spec.Names.Kind] = crd.Spec.Names.Plural + } + return kindToResourceName +} From d5f6169c7b4c0a1f290af9d770e687bea30909a4 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 26 Oct 2022 11:03:29 -0400 Subject: [PATCH 21/43] Fix tests with line break --- cli/cmd/install/install_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/cmd/install/install_test.go b/cli/cmd/install/install_test.go index 15bb3a6f69..1415ea5be9 100644 --- a/cli/cmd/install/install_test.go +++ b/cli/cmd/install/install_test.go @@ -521,7 +521,7 @@ func TestInstall(t *testing.T) { }, messages: []string{ "\n==> Checking if Consul can be installed\n ✓ No existing Consul installations found.\n ✓ No existing Consul persistent volume claims found\n ✓ No existing Consul secrets found.\n ✓ Valid enterprise Consul secret found.\n", - "\n==> Consul Installation Summary\n Name: consul\n Namespace: consul\n \n Helm value overrides\n -------------------\n global:\n enterpriseLicense:\n secretName: consul-license\n \n", + "\n==> Consul Installation Summary\n Name: consul\n Namespace: consul\n \n Helm value overrides\n --------------------\n global:\n enterpriseLicense:\n secretName: consul-license\n \n", "\n==> Installing Consul\n ✓ Downloaded charts.\n ✓ Consul installed in namespace \"consul\".\n", }, helmActionsRunner: &helm.MockActionRunner{}, @@ -558,7 +558,7 @@ func TestInstall(t *testing.T) { }, messages: []string{ "\n==> Checking if Consul can be installed\n ✓ No existing Consul installations found.\n ✓ No existing Consul persistent volume claims found\n ✓ No existing Consul secrets found.\n", - "\n==> Consul Installation Summary\n Name: consul\n Namespace: consul\n \n Helm value overrides\n -------------------\n connectInject:\n enabled: true\n metrics:\n defaultEnableMerging: true\n defaultEnabled: true\n enableGatewayMetrics: true\n controller:\n enabled: true\n global:\n metrics:\n enableAgentMetrics: true\n enabled: true\n name: consul\n prometheus:\n enabled: true\n server:\n replicas: 1\n ui:\n enabled: true\n service:\n enabled: true\n \n", + "\n==> Consul Installation Summary\n Name: consul\n Namespace: consul\n \n Helm value overrides\n --------------------\n connectInject:\n enabled: true\n metrics:\n defaultEnableMerging: true\n defaultEnabled: true\n enableGatewayMetrics: true\n controller:\n enabled: true\n global:\n metrics:\n enableAgentMetrics: true\n enabled: true\n name: consul\n prometheus:\n enabled: true\n server:\n replicas: 1\n ui:\n enabled: true\n service:\n enabled: true\n \n", "\n==> Installing Consul\n ✓ Downloaded charts.\n ✓ Consul installed in namespace \"consul\".\n", }, helmActionsRunner: &helm.MockActionRunner{}, @@ -574,7 +574,7 @@ func TestInstall(t *testing.T) { }, messages: []string{ "\n==> Checking if Consul can be installed\n ✓ No existing Consul installations found.\n ✓ No existing Consul persistent volume claims found\n ✓ No existing Consul secrets found.\n", - "\n==> Consul Installation Summary\n Name: consul\n Namespace: consul\n \n Helm value overrides\n -------------------\n connectInject:\n enabled: true\n controller:\n enabled: true\n global:\n acls:\n manageSystemACLs: true\n gossipEncryption:\n autoGenerate: true\n name: consul\n tls:\n enableAutoEncrypt: true\n enabled: true\n server:\n replicas: 1\n \n", + "\n==> Consul Installation Summary\n Name: consul\n Namespace: consul\n \n Helm value overrides\n --------------------\n connectInject:\n enabled: true\n controller:\n enabled: true\n global:\n acls:\n manageSystemACLs: true\n gossipEncryption:\n autoGenerate: true\n name: consul\n tls:\n enableAutoEncrypt: true\n enabled: true\n server:\n replicas: 1\n \n", "\n==> Installing Consul\n ✓ Downloaded charts.\n ✓ Consul installed in namespace \"consul\".\n", }, helmActionsRunner: &helm.MockActionRunner{}, From d31baf3588646a8d22ccd65bc1b0f3e1ef0fffc3 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 26 Oct 2022 11:04:30 -0400 Subject: [PATCH 22/43] Use uiLogger for consistency --- cli/cmd/uninstall/uninstall.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 91b50af82c..f1e28f8ab0 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -377,7 +377,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // Delete any custom resources managed by Consul. If they cannot be deleted, // patch the finalizers to be empty on each one. if releaseType == common.ReleaseTypeConsul { - c.UI.Output("Deleting custom resources managed by Consul", terminal.WithLibraryStyle()) + uiLogger("Deleting custom resources managed by Consul") crds, err := c.fetchCustomResourceDefinitions() if err != nil { return fmt.Errorf("unable to fetch Custom Resource Definitions for Consul deployment: %v", err) @@ -407,7 +407,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) if common.IsDeletionError(err) { - c.UI.Output("Patching finalizers on custom resources managed by Consul", terminal.WithLibraryStyle()) + uiLogger("Patching finalizers on custom resources managed by Consul") crs, err := c.fetchCustomResources(crds) if err != nil { return err From 55c6ada5c9ace60b43a1c4074c13bbea9186de18 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 26 Oct 2022 11:05:19 -0400 Subject: [PATCH 23/43] Fix tests to fetch crds --- cli/cmd/uninstall/uninstall_test.go | 117 ++++++++++------------------ 1 file changed, 42 insertions(+), 75 deletions(-) diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 743a3bb1e8..f20cfc6416 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -464,7 +464,10 @@ func TestFetchCustomResources(t *testing.T) { _, err = c.dynamic.Resource(nonConsulGRV).Namespace("default").Create(context.Background(), &nonConsulCR, metav1.CreateOptions{}) require.NoError(t, err) - actual, err := c.fetchCustomResources() + crds, err := c.fetchCustomResourceDefinitions() + require.NoError(t, err) + + actual, err := c.fetchCustomResources(crds) require.NoError(t, err) require.Len(t, actual, 1) require.Contains(t, actual, cr) @@ -489,14 +492,17 @@ func TestDeleteCustomResources(t *testing.T) { _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) require.NoError(t, err) - actual, err := c.fetchCustomResources() + crds, err := c.fetchCustomResourceDefinitions() + require.NoError(t, err) + + actual, err := c.fetchCustomResources(crds) require.NoError(t, err) require.Len(t, actual, 1) - err = c.deleteCustomResources([]unstructured.Unstructured{cr}) + err = c.deleteCustomResources([]unstructured.Unstructured{cr}, mapCRKindToResourceName(crds)) require.NoError(t, err) - actual, err = c.fetchCustomResources() + actual, err = c.fetchCustomResources(crds) require.NoError(t, err) require.Len(t, actual, 0) } @@ -520,10 +526,13 @@ func TestPatchCustomResources(t *testing.T) { _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) require.NoError(t, err) - err = c.patchCustomResources([]unstructured.Unstructured{cr}) + crds, err := c.fetchCustomResourceDefinitions() require.NoError(t, err) - actual, err := c.fetchCustomResources() + err = c.patchCustomResources([]unstructured.Unstructured{cr}, mapCRKindToResourceName(crds)) + require.NoError(t, err) + + actual, err := c.fetchCustomResources(crds) require.NoError(t, err) require.Len(t, actual, 1) require.Len(t, actual[0].GetFinalizers(), 0) @@ -535,7 +544,6 @@ func TestUninstall(t *testing.T) { messages []string helmActionsRunner *helm.MockActionRunner preProcessingFunc func() - withController bool expectedReturnCode int expectCheckedForConsulInstallations bool expectCheckedForConsulDemoInstallations bool @@ -547,7 +555,8 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul", + "\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -564,29 +573,6 @@ func TestUninstall(t *testing.T) { expectConsulUninstalled: true, expectConsulDemoUninstalled: false, }, - "uninstall when consul installation exists returns success with controller deployed": { - input: []string{}, - messages: []string{ - "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n", - "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", - }, - helmActionsRunner: &helm.MockActionRunner{ - CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { - if options.ReleaseName == "consul" { - return true, "consul", "consul", nil - } else { - return false, "", "", nil - } - }, - }, - withController: true, - expectedReturnCode: 0, - expectCheckedForConsulInstallations: true, - expectCheckedForConsulDemoInstallations: true, - expectConsulUninstalled: true, - expectConsulDemoUninstalled: false, - }, "uninstall when consul installation does not exist returns error": { input: []string{}, messages: []string{ @@ -614,33 +600,10 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n ✓ Successfully uninstalled Consul Helm release.\n", - "\n==> Other Consul Resources\n Deleting data for installation: \n Name: consul\n Namespace consul\n ✓ No PVCs found.\n ✓ No Consul secrets found.\n ✓ No Consul service accounts found.\n ✓ No Consul roles found.\n ✓ No Consul rolebindings found.\n ✓ No Consul jobs found.\n ✓ No Consul cluster roles found.\n ✓ No Consul cluster role bindings found.\n", - }, - helmActionsRunner: &helm.MockActionRunner{ - CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { - if options.ReleaseName == "consul" { - return true, "consul", "consul", nil - } else { - return false, "", "", nil - } - }, - }, - expectedReturnCode: 0, - expectCheckedForConsulInstallations: true, - expectCheckedForConsulDemoInstallations: true, - expectConsulUninstalled: true, - expectConsulDemoUninstalled: false, - }, - "uninstall with -wipe-data flag processes other resource and returns success with controller deployed": { - input: []string{ - "-wipe-data", - }, - messages: []string{ - "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n No existing Consul demo application installation found.\n", - "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n ✓ Successfully uninstalled Consul Helm release.\n", - "\n==> Other Consul Resources\n Deleting data for installation: \n Name: consul\n Namespace consul\n ✓ No PVCs found.\n ✓ No Consul secrets found.\n ✓ No Consul service accounts found.\n ✓ No Consul roles found.\n ✓ No Consul rolebindings found.\n ✓ No Consul jobs found.\n ✓ No Consul cluster roles found.\n ✓ No Consul cluster role bindings found.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul", + "\n ✓ Successfully uninstalled Consul Helm release.\n", + "\n==> Other Consul Resources\n Deleting data for installation: \n Name: consul\n Namespace consul", + "\n ✓ No PVCs found.\n ✓ No Consul secrets found.\n ✓ No Consul service accounts found.\n ✓ No Consul roles found.\n ✓ No Consul rolebindings found.\n ✓ No Consul jobs found.\n ✓ No Consul cluster roles found.\n ✓ No Consul cluster role bindings found.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -651,7 +614,6 @@ func TestUninstall(t *testing.T) { } }, }, - withController: true, expectedReturnCode: 0, expectCheckedForConsulInstallations: true, expectCheckedForConsulDemoInstallations: true, @@ -662,9 +624,11 @@ func TestUninstall(t *testing.T) { input: []string{}, messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n ✓ Existing Consul demo application installation found.\n", - "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo\n ✓ Successfully uninstalled Consul demo application Helm release.\n", + "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo", + "\n ✓ Successfully uninstalled Consul demo application Helm release.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul", + "\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -686,7 +650,8 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n ! Helm returned an error.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul", + "\n ! Helm returned an error.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -710,7 +675,8 @@ func TestUninstall(t *testing.T) { input: []string{}, messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n ✓ Existing Consul demo application installation found.\n", - "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo\n ! Helm returned an error.\n", + "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo", + "\n ! Helm returned an error.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -756,10 +722,8 @@ func TestUninstall(t *testing.T) { c.kubernetes = fake.NewSimpleClientset() c.apiext, c.dynamic = createClientsWithCrds() - if tc.withController { - _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) - require.NoError(t, err) - } + _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + require.NoError(t, err) mock := tc.helmActionsRunner c.helmActionsRunner = mock @@ -771,18 +735,21 @@ func TestUninstall(t *testing.T) { "--auto-approve", }, tc.input...) returnCode := c.Run(input) - require.Equal(t, tc.expectedReturnCode, returnCode) + output := buf.String() + require.Equal(t, tc.expectedReturnCode, returnCode, output) + require.Equal(t, tc.expectCheckedForConsulInstallations, mock.CheckedForConsulInstallations) require.Equal(t, tc.expectCheckedForConsulDemoInstallations, mock.CheckedForConsulDemoInstallations) require.Equal(t, tc.expectConsulUninstalled, mock.ConsulUninstalled) require.Equal(t, tc.expectConsulDemoUninstalled, mock.ConsulDemoUninstalled) - output := buf.String() for _, msg := range tc.messages { require.Contains(t, output, msg) } - if tc.withController { - crs, err := c.fetchCustomResources() + if tc.expectConsulUninstalled { + crds, err := c.fetchCustomResourceDefinitions() + require.NoError(t, err) + crs, err := c.fetchCustomResources(crds) require.NoError(t, err) require.Len(t, crs, 0) } @@ -807,8 +774,8 @@ func createClientsWithCrds() (apiext.Interface, dynamic.Interface) { Spec: apiextv1.CustomResourceDefinitionSpec{ Group: "consul.hashicorp.com", Names: apiextv1.CustomResourceDefinitionNames{ - Plural: "servicedefaults", - ListKind: "ServiceDefaultsList", + Plural: "servicedefaults", + Kind: "ServiceDefaults", }, Scope: "Namespaced", Versions: []apiextv1.CustomResourceDefinitionVersion{ @@ -825,8 +792,8 @@ func createClientsWithCrds() (apiext.Interface, dynamic.Interface) { Spec: apiextv1.CustomResourceDefinitionSpec{ Group: "example.com", Names: apiextv1.CustomResourceDefinitionNames{ - Plural: "examples", - ListKind: "ExamplesList", + Plural: "examples", + Kind: "Example", }, Scope: "Namespaced", Versions: []apiextv1.CustomResourceDefinitionVersion{ From 2f8686c85d5a5f803a1c78cbd4d121e9eed154e4 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 26 Oct 2022 11:10:57 -0400 Subject: [PATCH 24/43] Test mapCRKindToResource --- cli/cmd/uninstall/uninstall_test.go | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index f20cfc6416..221aff75cf 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -538,6 +538,60 @@ func TestPatchCustomResources(t *testing.T) { require.Len(t, actual[0].GetFinalizers(), 0) } +func TestMapKindToResource(t *testing.T) { + crds := apiextv1.CustomResourceDefinitionList{ + Items: []apiextv1.CustomResourceDefinition{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "servicedefaults.consul.hashicorp.com", + Labels: map[string]string{ + "app": "consul", + }, + }, + Spec: apiextv1.CustomResourceDefinitionSpec{ + Group: "consul.hashicorp.com", + Names: apiextv1.CustomResourceDefinitionNames{ + Plural: "servicedefaults", + Kind: "ServiceDefaults", + }, + Scope: "Namespaced", + Versions: []apiextv1.CustomResourceDefinitionVersion{ + { + Name: "v1alpha1", + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "examples.example.com", + }, + Spec: apiextv1.CustomResourceDefinitionSpec{ + Group: "example.com", + Names: apiextv1.CustomResourceDefinitionNames{ + Plural: "examples", + Kind: "Example", + }, + Scope: "Namespaced", + Versions: []apiextv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + }, + }, + }, + }, + }, + } + + expected := map[string]string{ + "ServiceDefaults": "servicedefaults", + "Example": "examples", + } + + actual := mapCRKindToResourceName(&crds) + require.Equal(t, expected, actual) +} + func TestUninstall(t *testing.T) { cases := map[string]struct { input []string From e41d4e6b5ae34ba6134f11f87305d908edf0a88d Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 26 Oct 2022 11:34:19 -0400 Subject: [PATCH 25/43] Use DurationVar for timeout --- cli/cmd/uninstall/uninstall.go | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index f1e28f8ab0..54469bf894 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -42,7 +42,7 @@ const ( defaultWipeData = false flagTimeout = "timeout" - defaultTimeout = "10m" + defaultTimeout = 10 * time.Minute flagContext = "context" flagKubeconfig = "kubeconfig" @@ -64,8 +64,7 @@ type Command struct { flagReleaseName string flagAutoApprove bool flagWipeData bool - flagTimeout string - timeoutDuration time.Duration + flagTimeout time.Duration flagKubeConfig string flagKubeContext string @@ -101,7 +100,7 @@ func (c *Command) init() { Default: defaultAnyReleaseName, Usage: "Name of the installation. This can be used to uninstall and/or delete the resources of a specific Helm release.", }) - f.StringVar(&flag.StringVar{ + f.DurationVar(&flag.DurationVar{ Name: flagTimeout, Target: &c.flagTimeout, Default: defaultTimeout, @@ -155,12 +154,6 @@ func (c *Command) Run(args []string) int { c.UI.Output("Can't set -wipe-data alone. Omit this flag to interactively uninstall, or use it with -auto-approve to wipe all data during the uninstall.", terminal.WithErrorStyle()) return 1 } - duration, err := time.ParseDuration(c.flagTimeout) - if err != nil { - c.UI.Output("unable to parse -%s: %s", flagTimeout, err, terminal.WithErrorStyle()) - return 1 - } - c.timeoutDuration = duration // helmCLI.New() will create a settings object which is used by the Helm Go SDK calls. settings := helmCLI.New() @@ -182,7 +175,7 @@ func (c *Command) Run(args []string) int { } actionConfig := new(action.Configuration) - actionConfig, err = helm.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) + actionConfig, err := helm.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) return 1 @@ -427,7 +420,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin } uninstall := action.NewUninstall(actionConfig) - uninstall.Timeout = c.timeoutDuration + uninstall.Timeout = c.flagTimeout res, err := c.helmActionsRunner.Uninstall(uninstall, releaseName) if err != nil { From 1371f4502ecbdc01736bcbfc0a7f6f4a895ee766 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 26 Oct 2022 11:42:43 -0400 Subject: [PATCH 26/43] Add CHANGELOG entry for PR 1623 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd4824d7cc..2e2e4ced82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ FEATURES: IMPROVEMENTS: * CLI * Update minimum go version for project to 1.19 [[GH-1633](https://github.com/hashicorp/consul-k8s/pull/1633)] + * `consul-k8s uninstall` now deletes custom resources when uninstalling Consul. [[GH-1623](https://github.com/hashicorp/consul-k8s/pull/1623)] * Control Plane * Update minimum go version for project to 1.19 [[GH-1633](https://github.com/hashicorp/consul-k8s/pull/1633)] * Remove unneeded `agent:read` ACL permissions from mesh gateway policy. [[GH-1255](https://github.com/hashicorp/consul-k8s/pull/1255)] From 862cce653987e2be741a0c4a7bc3a87ed4a3895d Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Mon, 31 Oct 2022 14:06:58 -0400 Subject: [PATCH 27/43] Remove merge conflict in workflows/test --- .github/workflows/test.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4f7d12cce4..93e4923f39 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -344,11 +344,7 @@ jobs: acceptance: needs: [ get-product-version, dev-upload-docker, get-go-version ] -<<<<<<< HEAD uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@main -======= - uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@536f034d6647fdadca8892036d0b06e28d1c9a57 ->>>>>>> d5d87e8c (Change uses to point to Git hash) with: name: acceptance directory: acceptance/tests From 12ca57e7f7ac28f27d4e3cf3e8e8f5210047288e Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Mon, 31 Oct 2022 17:08:13 -0400 Subject: [PATCH 28/43] Include Deletion of CRs message in TestUninstall --- cli/cmd/uninstall/uninstall_test.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 221aff75cf..c3fbcc82f2 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -609,8 +609,7 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul", - "\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -654,8 +653,7 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul", - "\n ✓ Successfully uninstalled Consul Helm release.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ✓ Successfully uninstalled Consul Helm release.\n", "\n==> Other Consul Resources\n Deleting data for installation: \n Name: consul\n Namespace consul", "\n ✓ No PVCs found.\n ✓ No Consul secrets found.\n ✓ No Consul service accounts found.\n ✓ No Consul roles found.\n ✓ No Consul rolebindings found.\n ✓ No Consul jobs found.\n ✓ No Consul cluster roles found.\n ✓ No Consul cluster role bindings found.\n", }, @@ -681,8 +679,7 @@ func TestUninstall(t *testing.T) { "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo", "\n ✓ Successfully uninstalled Consul demo application Helm release.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul", - "\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -704,8 +701,7 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul", - "\n ! Helm returned an error.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ! Helm returned an error.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { From bc4f07b7f4466dcd49f447904612f37a49fe4c49 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Mon, 31 Oct 2022 18:02:30 -0400 Subject: [PATCH 29/43] Re-unify test strings --- cli/cmd/uninstall/uninstall_test.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index c3fbcc82f2..658295d6c8 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -7,13 +7,14 @@ import ( "flag" "fmt" "io" + "os" + "testing" + apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes/fake" - "os" - "testing" "github.com/hashicorp/consul-k8s/cli/common" cmnFlag "github.com/hashicorp/consul-k8s/cli/common/flag" @@ -654,8 +655,7 @@ func TestUninstall(t *testing.T) { "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ✓ Successfully uninstalled Consul Helm release.\n", - "\n==> Other Consul Resources\n Deleting data for installation: \n Name: consul\n Namespace consul", - "\n ✓ No PVCs found.\n ✓ No Consul secrets found.\n ✓ No Consul service accounts found.\n ✓ No Consul roles found.\n ✓ No Consul rolebindings found.\n ✓ No Consul jobs found.\n ✓ No Consul cluster roles found.\n ✓ No Consul cluster role bindings found.\n", + "\n==> Other Consul Resources\n Deleting data for installation: \n Name: consul\n Namespace consul\n ✓ No PVCs found.\n ✓ No Consul secrets found.\n ✓ No Consul service accounts found.\n ✓ No Consul roles found.\n ✓ No Consul rolebindings found.\n ✓ No Consul jobs found.\n ✓ No Consul cluster roles found.\n ✓ No Consul cluster role bindings found.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -676,8 +676,7 @@ func TestUninstall(t *testing.T) { input: []string{}, messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n ✓ Existing Consul demo application installation found.\n", - "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo", - "\n ✓ Successfully uninstalled Consul demo application Helm release.\n", + "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo\n ✓ Successfully uninstalled Consul demo application Helm release.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", }, @@ -725,8 +724,7 @@ func TestUninstall(t *testing.T) { input: []string{}, messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n ✓ Existing Consul demo application installation found.\n", - "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo", - "\n ! Helm returned an error.\n", + "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo\n ! Helm returned an error.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { From 01131c1326d3a6f28d7c5cc40712c1cce9418191 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 12:40:35 -0400 Subject: [PATCH 30/43] Use k8serrors and test CR in another ns --- cli/cmd/uninstall/uninstall.go | 3 ++- cli/cmd/uninstall/uninstall_test.go | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 54469bf894..d9bebeb3fa 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -2,6 +2,7 @@ package uninstall import ( "fmt" + k8serrors "k8s.io/apimachinery/pkg/api/errors" "os" "strings" "sync" @@ -521,7 +522,7 @@ func (c *Command) patchCustomResources(crs []unstructured.Unstructured, kindToRe Resource(target). Namespace(cr.GetNamespace()). Patch(c.Ctx, cr.GetName(), types.JSONPatchType, finalizerPatch, metav1.PatchOptions{}) - if common.IgnoreNotFoundError(err) != nil { + if err != nil && !k8serrors.IsNotFound(err) { return err } } diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 658295d6c8..2b8f459cb4 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -446,7 +446,7 @@ func TestFetchCustomResources(t *testing.T) { }, }, } - nonConsulCR := unstructured.Unstructured{ + nonConsulCR1 := unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "example.com/v1", "kind": "Example", @@ -456,13 +456,26 @@ func TestFetchCustomResources(t *testing.T) { }, }, } + nonConsulCR2 := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "example.com/v1", + "kind": "Example", + "metadata": map[string]interface{}{ + "name": "example-resource", + "namespace": "other", + }, + }, + } c := getInitializedCommand(t, nil) + c.kubernetes = fake.NewSimpleClientset(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "other"}}) c.apiext, c.dynamic = createClientsWithCrds() _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.dynamic.Resource(nonConsulGRV).Namespace("default").Create(context.Background(), &nonConsulCR, metav1.CreateOptions{}) + _, err = c.dynamic.Resource(nonConsulGRV).Namespace("default").Create(context.Background(), &nonConsulCR1, metav1.CreateOptions{}) + require.NoError(t, err) + _, err = c.dynamic.Resource(nonConsulGRV).Namespace("other").Create(context.Background(), &nonConsulCR2, metav1.CreateOptions{}) require.NoError(t, err) crds, err := c.fetchCustomResourceDefinitions() @@ -472,7 +485,8 @@ func TestFetchCustomResources(t *testing.T) { require.NoError(t, err) require.Len(t, actual, 1) require.Contains(t, actual, cr) - require.NotContains(t, actual, nonConsulCR) + require.NotContains(t, actual, nonConsulCR1) + require.NotContains(t, actual, nonConsulCR2) } func TestDeleteCustomResources(t *testing.T) { From 2581d840dd14c20661ed44bbdb7e3358a125c7b8 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 12:41:20 -0400 Subject: [PATCH 31/43] Comment out GHA --- .github/workflows/test.yml | 76 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 93e4923f39..ac4038b50f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -342,43 +342,43 @@ jobs: target: release-default tags: docker.io/hashicorppreview/${{ env.repo }}-control-plane:${{ env.version }}-pr-${{ github.sha }} - acceptance: - needs: [ get-product-version, dev-upload-docker, get-go-version ] - uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@main - with: - name: acceptance - directory: acceptance/tests - go-version: ${{ needs.get-go-version.outputs.go-version }} - additional-flags: "-use-kind -kubecontext=kind-dc1 -secondary-kubecontext=kind-dc2 -consul-image=docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.14-dev" - gotestsum-version: 1.8.2 - consul-k8s-image: docker.io/hashicorppreview/${{ github.event.repository.name }}-control-plane:${{ needs.get-product-version.outputs.product-version }}-pr-${{ github.sha }} - secrets: - CONSUL_ENT_LICENSE: ${{ secrets.CONSUL_ENT_LICENSE }} - - acceptance-tproxy: - needs: [ get-product-version, dev-upload-docker, get-go-version ] - uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@main - with: - name: acceptance-tproxy - directory: acceptance/tests - go-version: ${{ needs.get-go-version.outputs.go-version }} - additional-flags: "-use-kind -kubecontext=kind-dc1 -secondary-kubecontext=kind-dc2 -enable-transparent-proxy -consul-image=docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.14-dev" - gotestsum-version: 1.8.2 - consul-k8s-image: docker.io/hashicorppreview/${{ github.event.repository.name }}-control-plane:${{ needs.get-product-version.outputs.product-version }}-pr-${{ github.sha }} - secrets: - CONSUL_ENT_LICENSE: ${{ secrets.CONSUL_ENT_LICENSE }} - - acceptance-cni: - needs: [ get-product-version, dev-upload-docker, get-go-version ] - uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@main - with: - name: acceptance - directory: acceptance/tests - go-version: ${{ needs.get-go-version.outputs.go-version }} - additional-flags: "-use-kind -kubecontext=kind-dc1 -secondary-kubecontext=kind-dc2 -enable-transparent-proxy -enable-cni -consul-image=docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.14-dev" - gotestsum-version: 1.8.2 - consul-k8s-image: docker.io/hashicorppreview/${{ github.event.repository.name }}-control-plane:${{ needs.get-product-version.outputs.product-version }}-pr-${{ github.sha }} - secrets: - CONSUL_ENT_LICENSE: ${{ secrets.CONSUL_ENT_LICENSE }} + # acceptance: + # needs: [ get-product-version, dev-upload-docker, get-go-version ] + # uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@main + # with: + # name: acceptance + # directory: acceptance/tests + # go-version: ${{ needs.get-go-version.outputs.go-version }} + # additional-flags: "-use-kind -kubecontext=kind-dc1 -secondary-kubecontext=kind-dc2 -consul-image=docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.14-dev" + # gotestsum-version: 1.8.2 + # consul-k8s-image: docker.io/hashicorppreview/${{ github.event.repository.name }}-control-plane:${{ needs.get-product-version.outputs.product-version }}-pr-${{ github.sha }} + # secrets: + # CONSUL_ENT_LICENSE: ${{ secrets.CONSUL_ENT_LICENSE }} + + # acceptance-tproxy: + # needs: [ get-product-version, dev-upload-docker, get-go-version ] + # uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@main + # with: + # name: acceptance-tproxy + # directory: acceptance/tests + # go-version: ${{ needs.get-go-version.outputs.go-version }} + # additional-flags: "-use-kind -kubecontext=kind-dc1 -secondary-kubecontext=kind-dc2 -enable-transparent-proxy -consul-image=docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.14-dev" + # gotestsum-version: 1.8.2 + # consul-k8s-image: docker.io/hashicorppreview/${{ github.event.repository.name }}-control-plane:${{ needs.get-product-version.outputs.product-version }}-pr-${{ github.sha }} + # secrets: + # CONSUL_ENT_LICENSE: ${{ secrets.CONSUL_ENT_LICENSE }} + + # acceptance-cni: + # needs: [ get-product-version, dev-upload-docker, get-go-version ] + # uses: hashicorp/consul-k8s/.github/workflows/reusable-acceptance.yml@main + # with: + # name: acceptance + # directory: acceptance/tests + # go-version: ${{ needs.get-go-version.outputs.go-version }} + # additional-flags: "-use-kind -kubecontext=kind-dc1 -secondary-kubecontext=kind-dc2 -enable-transparent-proxy -enable-cni -consul-image=docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.14-dev" + # gotestsum-version: 1.8.2 + # consul-k8s-image: docker.io/hashicorppreview/${{ github.event.repository.name }}-control-plane:${{ needs.get-product-version.outputs.product-version }}-pr-${{ github.sha }} + # secrets: + # CONSUL_ENT_LICENSE: ${{ secrets.CONSUL_ENT_LICENSE }} From 56fdd076ef37fd2a1a2890ddb2ca653902d62cd6 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 12:42:54 -0400 Subject: [PATCH 32/43] Rename k8s clients --- cli/cmd/uninstall/uninstall.go | 63 ++++++++--------- cli/cmd/uninstall/uninstall_test.go | 104 ++++++++++++++-------------- 2 files changed, 84 insertions(+), 83 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index d9bebeb3fa..45915ab4f2 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -2,12 +2,13 @@ package uninstall import ( "fmt" - k8serrors "k8s.io/apimachinery/pkg/api/errors" "os" "strings" "sync" "time" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "github.com/cenkalti/backoff" "github.com/hashicorp/consul-k8s/cli/common" "github.com/hashicorp/consul-k8s/cli/common/flag" @@ -55,9 +56,9 @@ type Command struct { helmActionsRunner helm.HelmActionsRunner // Configuration for interacting with Kubernetes. - kubernetes kubernetes.Interface - dynamic dynamic.Interface - apiext apiext.Interface + k8sClient kubernetes.Interface + dynamicK8sClient dynamic.Interface + apiextK8sClient apiext.Interface set *flag.Sets @@ -323,20 +324,20 @@ func (c *Command) initKubernetes(settings *helmCLI.EnvSettings) error { return err } - if c.kubernetes == nil { - if c.kubernetes, err = kubernetes.NewForConfig(restConfig); err != nil { + if c.k8sClient == nil { + if c.k8sClient, err = kubernetes.NewForConfig(restConfig); err != nil { return err } } - if c.dynamic == nil { - if c.dynamic, err = dynamic.NewForConfig(restConfig); err != nil { + if c.dynamicK8sClient == nil { + if c.dynamicK8sClient, err = dynamic.NewForConfig(restConfig); err != nil { return err } } - if c.apiext == nil { - if c.apiext, err = apiext.NewForConfig(restConfig); err != nil { + if c.apiextK8sClient == nil { + if c.apiextK8sClient, err = apiext.NewForConfig(restConfig); err != nil { return err } } @@ -438,7 +439,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // fetchCustomResourceDefinitions fetches all Custom Resource Definitions managed by Consul. func (c *Command) fetchCustomResourceDefinitions() (*apiextv1.CustomResourceDefinitionList, error) { - return c.apiext.ApiextensionsV1().CustomResourceDefinitions().List(c.Ctx, metav1.ListOptions{ + return c.apiextK8sClient.ApiextensionsV1().CustomResourceDefinitions().List(c.Ctx, metav1.ListOptions{ LabelSelector: "app=consul", }) } @@ -455,7 +456,7 @@ func (c *Command) fetchCustomResources(crds *apiextv1.CustomResourceDefinitionLi Resource: crd.Spec.Names.Plural, } - crList, err := c.dynamic.Resource(target).List(c.Ctx, metav1.ListOptions{}) + crList, err := c.dynamicK8sClient.Resource(target).List(c.Ctx, metav1.ListOptions{}) if err != nil { return nil, err } @@ -484,7 +485,7 @@ func (c *Command) deleteCustomResources(crs []unstructured.Unstructured, kindToR Resource: kindToResource[cr.GetKind()], } - err := c.dynamic. + err := c.dynamicK8sClient. Resource(target). Namespace(cr.GetNamespace()). Delete(c.Ctx, cr.GetName(), metav1.DeleteOptions{}) @@ -518,7 +519,7 @@ func (c *Command) patchCustomResources(crs []unstructured.Unstructured, kindToRe Resource: kindToResource[cr.GetKind()], } - _, err := c.dynamic. + _, err := c.dynamicK8sClient. Resource(target). Namespace(cr.GetNamespace()). Patch(c.Ctx, cr.GetName(), types.JSONPatchType, finalizerPatch, metav1.PatchOptions{}) @@ -581,7 +582,7 @@ func (c *Command) findExistingInstallation(options *helm.CheckForInstallationsOp func (c *Command) deletePVCs(foundReleaseName, foundReleaseNamespace string) error { var pvcNames []string pvcSelector := metav1.ListOptions{LabelSelector: fmt.Sprintf("release=%s", foundReleaseName)} - pvcs, err := c.kubernetes.CoreV1().PersistentVolumeClaims(foundReleaseNamespace).List(c.Ctx, pvcSelector) + pvcs, err := c.k8sClient.CoreV1().PersistentVolumeClaims(foundReleaseNamespace).List(c.Ctx, pvcSelector) if err != nil { return fmt.Errorf("deletePVCs: %s", err) } @@ -590,14 +591,14 @@ func (c *Command) deletePVCs(foundReleaseName, foundReleaseNamespace string) err return nil } for _, pvc := range pvcs.Items { - err := c.kubernetes.CoreV1().PersistentVolumeClaims(foundReleaseNamespace).Delete(c.Ctx, pvc.Name, metav1.DeleteOptions{}) + err := c.k8sClient.CoreV1().PersistentVolumeClaims(foundReleaseNamespace).Delete(c.Ctx, pvc.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("deletePVCs: error deleting PVC %q: %s", pvc.Name, err) } pvcNames = append(pvcNames, pvc.Name) } err = backoff.Retry(func() error { - pvcs, err := c.kubernetes.CoreV1().PersistentVolumeClaims(foundReleaseNamespace).List(c.Ctx, pvcSelector) + pvcs, err := c.k8sClient.CoreV1().PersistentVolumeClaims(foundReleaseNamespace).List(c.Ctx, pvcSelector) if err != nil { return fmt.Errorf("deletePVCs: %s", err) } @@ -620,7 +621,7 @@ func (c *Command) deletePVCs(foundReleaseName, foundReleaseNamespace string) err // deleteSecrets deletes any secrets that have the label "managed-by" set to "consul-k8s". func (c *Command) deleteSecrets(foundReleaseNamespace string) error { - secrets, err := c.kubernetes.CoreV1().Secrets(foundReleaseNamespace).List(c.Ctx, metav1.ListOptions{ + secrets, err := c.k8sClient.CoreV1().Secrets(foundReleaseNamespace).List(c.Ctx, metav1.ListOptions{ LabelSelector: common.CLILabelKey + "=" + common.CLILabelValue, }) if err != nil { @@ -632,7 +633,7 @@ func (c *Command) deleteSecrets(foundReleaseNamespace string) error { } var secretNames []string for _, secret := range secrets.Items { - err := c.kubernetes.CoreV1().Secrets(foundReleaseNamespace).Delete(c.Ctx, secret.Name, metav1.DeleteOptions{}) + err := c.k8sClient.CoreV1().Secrets(foundReleaseNamespace).Delete(c.Ctx, secret.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("deleteSecrets: error deleting Secret %q: %s", secret.Name, err) } @@ -651,7 +652,7 @@ func (c *Command) deleteSecrets(foundReleaseNamespace string) error { func (c *Command) deleteServiceAccounts(foundReleaseName, foundReleaseNamespace string) error { var serviceAccountNames []string saSelector := metav1.ListOptions{LabelSelector: fmt.Sprintf("release=%s", foundReleaseName)} - sas, err := c.kubernetes.CoreV1().ServiceAccounts(foundReleaseNamespace).List(c.Ctx, saSelector) + sas, err := c.k8sClient.CoreV1().ServiceAccounts(foundReleaseNamespace).List(c.Ctx, saSelector) if err != nil { return fmt.Errorf("deleteServiceAccounts: %s", err) } @@ -660,7 +661,7 @@ func (c *Command) deleteServiceAccounts(foundReleaseName, foundReleaseNamespace return nil } for _, sa := range sas.Items { - err := c.kubernetes.CoreV1().ServiceAccounts(foundReleaseNamespace).Delete(c.Ctx, sa.Name, metav1.DeleteOptions{}) + err := c.k8sClient.CoreV1().ServiceAccounts(foundReleaseNamespace).Delete(c.Ctx, sa.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("deleteServiceAccounts: error deleting ServiceAccount %q: %s", sa.Name, err) } @@ -679,7 +680,7 @@ func (c *Command) deleteServiceAccounts(foundReleaseName, foundReleaseNamespace func (c *Command) deleteRoles(foundReleaseName, foundReleaseNamespace string) error { var roleNames []string roleSelector := metav1.ListOptions{LabelSelector: fmt.Sprintf("release=%s", foundReleaseName)} - roles, err := c.kubernetes.RbacV1().Roles(foundReleaseNamespace).List(c.Ctx, roleSelector) + roles, err := c.k8sClient.RbacV1().Roles(foundReleaseNamespace).List(c.Ctx, roleSelector) if err != nil { return fmt.Errorf("deleteRoles: %s", err) } @@ -688,7 +689,7 @@ func (c *Command) deleteRoles(foundReleaseName, foundReleaseNamespace string) er return nil } for _, role := range roles.Items { - err := c.kubernetes.RbacV1().Roles(foundReleaseNamespace).Delete(c.Ctx, role.Name, metav1.DeleteOptions{}) + err := c.k8sClient.RbacV1().Roles(foundReleaseNamespace).Delete(c.Ctx, role.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("deleteRoles: error deleting Role %q: %s", role.Name, err) } @@ -707,7 +708,7 @@ func (c *Command) deleteRoles(foundReleaseName, foundReleaseNamespace string) er func (c *Command) deleteRoleBindings(foundReleaseName, foundReleaseNamespace string) error { var rolebindingNames []string rolebindingSelector := metav1.ListOptions{LabelSelector: fmt.Sprintf("release=%s", foundReleaseName)} - rolebindings, err := c.kubernetes.RbacV1().RoleBindings(foundReleaseNamespace).List(c.Ctx, rolebindingSelector) + rolebindings, err := c.k8sClient.RbacV1().RoleBindings(foundReleaseNamespace).List(c.Ctx, rolebindingSelector) if err != nil { return fmt.Errorf("deleteRoleBindings: %s", err) } @@ -716,7 +717,7 @@ func (c *Command) deleteRoleBindings(foundReleaseName, foundReleaseNamespace str return nil } for _, rolebinding := range rolebindings.Items { - err := c.kubernetes.RbacV1().RoleBindings(foundReleaseNamespace).Delete(c.Ctx, rolebinding.Name, metav1.DeleteOptions{}) + err := c.k8sClient.RbacV1().RoleBindings(foundReleaseNamespace).Delete(c.Ctx, rolebinding.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("deleteRoleBindings: error deleting Role %q: %s", rolebinding.Name, err) } @@ -735,7 +736,7 @@ func (c *Command) deleteRoleBindings(foundReleaseName, foundReleaseNamespace str func (c *Command) deleteJobs(foundReleaseName, foundReleaseNamespace string) error { var jobNames []string jobSelector := metav1.ListOptions{LabelSelector: fmt.Sprintf("release=%s", foundReleaseName)} - jobs, err := c.kubernetes.BatchV1().Jobs(foundReleaseNamespace).List(c.Ctx, jobSelector) + jobs, err := c.k8sClient.BatchV1().Jobs(foundReleaseNamespace).List(c.Ctx, jobSelector) if err != nil { return fmt.Errorf("deleteJobs: %s", err) } @@ -744,7 +745,7 @@ func (c *Command) deleteJobs(foundReleaseName, foundReleaseNamespace string) err return nil } for _, job := range jobs.Items { - err := c.kubernetes.BatchV1().Jobs(foundReleaseNamespace).Delete(c.Ctx, job.Name, metav1.DeleteOptions{}) + err := c.k8sClient.BatchV1().Jobs(foundReleaseNamespace).Delete(c.Ctx, job.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("deleteJobs: error deleting Job %q: %s", job.Name, err) } @@ -763,7 +764,7 @@ func (c *Command) deleteJobs(foundReleaseName, foundReleaseNamespace string) err func (c *Command) deleteClusterRoles(foundReleaseName string) error { var clusterRolesNames []string clusterRolesSelector := metav1.ListOptions{LabelSelector: fmt.Sprintf("release=%s", foundReleaseName)} - clusterRoles, err := c.kubernetes.RbacV1().ClusterRoles().List(c.Ctx, clusterRolesSelector) + clusterRoles, err := c.k8sClient.RbacV1().ClusterRoles().List(c.Ctx, clusterRolesSelector) if err != nil { return fmt.Errorf("deleteClusterRoles: %s", err) } @@ -772,7 +773,7 @@ func (c *Command) deleteClusterRoles(foundReleaseName string) error { return nil } for _, clusterRole := range clusterRoles.Items { - err := c.kubernetes.RbacV1().ClusterRoles().Delete(c.Ctx, clusterRole.Name, metav1.DeleteOptions{}) + err := c.k8sClient.RbacV1().ClusterRoles().Delete(c.Ctx, clusterRole.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("deleteClusterRoles: error deleting cluster role %q: %s", clusterRole.Name, err) } @@ -791,7 +792,7 @@ func (c *Command) deleteClusterRoles(foundReleaseName string) error { func (c *Command) deleteClusterRoleBindings(foundReleaseName string) error { var clusterRoleBindingsNames []string clusterRoleBindingsSelector := metav1.ListOptions{LabelSelector: fmt.Sprintf("release=%s", foundReleaseName)} - clusterRoleBindings, err := c.kubernetes.RbacV1().ClusterRoleBindings().List(c.Ctx, clusterRoleBindingsSelector) + clusterRoleBindings, err := c.k8sClient.RbacV1().ClusterRoleBindings().List(c.Ctx, clusterRoleBindingsSelector) if err != nil { return fmt.Errorf("deleteClusterRoleBindings: %s", err) } @@ -800,7 +801,7 @@ func (c *Command) deleteClusterRoleBindings(foundReleaseName string) error { return nil } for _, clusterRoleBinding := range clusterRoleBindings.Items { - err := c.kubernetes.RbacV1().ClusterRoleBindings().Delete(c.Ctx, clusterRoleBinding.Name, metav1.DeleteOptions{}) + err := c.k8sClient.RbacV1().ClusterRoleBindings().Delete(c.Ctx, clusterRoleBinding.Name, metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("deleteClusterRoleBindings: error deleting cluster role binding %q: %s", clusterRoleBinding.Name, err) } diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 2b8f459cb4..e770363bfb 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -51,7 +51,7 @@ var ( func TestDeletePVCs(t *testing.T) { c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() pvc := &v1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ Name: "consul-server-test1", @@ -76,15 +76,15 @@ func TestDeletePVCs(t *testing.T) { }, }, } - _, err := c.kubernetes.CoreV1().PersistentVolumeClaims("default").Create(context.Background(), pvc, metav1.CreateOptions{}) + _, err := c.k8sClient.CoreV1().PersistentVolumeClaims("default").Create(context.Background(), pvc, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.CoreV1().PersistentVolumeClaims("default").Create(context.Background(), pvc2, metav1.CreateOptions{}) + _, err = c.k8sClient.CoreV1().PersistentVolumeClaims("default").Create(context.Background(), pvc2, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.CoreV1().PersistentVolumeClaims("default").Create(context.Background(), pvc3, metav1.CreateOptions{}) + _, err = c.k8sClient.CoreV1().PersistentVolumeClaims("default").Create(context.Background(), pvc3, metav1.CreateOptions{}) require.NoError(t, err) err = c.deletePVCs("consul", "default") require.NoError(t, err) - pvcs, err := c.kubernetes.CoreV1().PersistentVolumeClaims("default").List(context.Background(), metav1.ListOptions{}) + pvcs, err := c.k8sClient.CoreV1().PersistentVolumeClaims("default").List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) require.Len(t, pvcs.Items, 1) require.Equal(t, pvcs.Items[0].Name, pvc3.Name) @@ -92,7 +92,7 @@ func TestDeletePVCs(t *testing.T) { func TestDeleteSecrets(t *testing.T) { c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "consul-test-secret1", @@ -118,15 +118,15 @@ func TestDeleteSecrets(t *testing.T) { }, }, } - _, err := c.kubernetes.CoreV1().Secrets("default").Create(context.Background(), secret, metav1.CreateOptions{}) + _, err := c.k8sClient.CoreV1().Secrets("default").Create(context.Background(), secret, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.CoreV1().Secrets("default").Create(context.Background(), secret2, metav1.CreateOptions{}) + _, err = c.k8sClient.CoreV1().Secrets("default").Create(context.Background(), secret2, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.CoreV1().Secrets("default").Create(context.Background(), secret3, metav1.CreateOptions{}) + _, err = c.k8sClient.CoreV1().Secrets("default").Create(context.Background(), secret3, metav1.CreateOptions{}) require.NoError(t, err) err = c.deleteSecrets("default") require.NoError(t, err) - secrets, err := c.kubernetes.CoreV1().Secrets("default").List(context.Background(), metav1.ListOptions{}) + secrets, err := c.k8sClient.CoreV1().Secrets("default").List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) // Only secret1 should have been deleted, secret2 and secret 3 persist since it doesn't have the label. @@ -135,7 +135,7 @@ func TestDeleteSecrets(t *testing.T) { func TestDeleteServiceAccounts(t *testing.T) { c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() sa := &v1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: "consul-test-sa1", @@ -160,15 +160,15 @@ func TestDeleteServiceAccounts(t *testing.T) { }, }, } - _, err := c.kubernetes.CoreV1().ServiceAccounts("default").Create(context.Background(), sa, metav1.CreateOptions{}) + _, err := c.k8sClient.CoreV1().ServiceAccounts("default").Create(context.Background(), sa, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.CoreV1().ServiceAccounts("default").Create(context.Background(), sa2, metav1.CreateOptions{}) + _, err = c.k8sClient.CoreV1().ServiceAccounts("default").Create(context.Background(), sa2, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.CoreV1().ServiceAccounts("default").Create(context.Background(), sa3, metav1.CreateOptions{}) + _, err = c.k8sClient.CoreV1().ServiceAccounts("default").Create(context.Background(), sa3, metav1.CreateOptions{}) require.NoError(t, err) err = c.deleteServiceAccounts("consul", "default") require.NoError(t, err) - sas, err := c.kubernetes.CoreV1().ServiceAccounts("default").List(context.Background(), metav1.ListOptions{}) + sas, err := c.k8sClient.CoreV1().ServiceAccounts("default").List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) require.Len(t, sas.Items, 1) require.Equal(t, sas.Items[0].Name, sa3.Name) @@ -176,7 +176,7 @@ func TestDeleteServiceAccounts(t *testing.T) { func TestDeleteRoles(t *testing.T) { c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() role := &rbacv1.Role{ ObjectMeta: metav1.ObjectMeta{ Name: "consul-test-role1", @@ -201,15 +201,15 @@ func TestDeleteRoles(t *testing.T) { }, }, } - _, err := c.kubernetes.RbacV1().Roles("default").Create(context.Background(), role, metav1.CreateOptions{}) + _, err := c.k8sClient.RbacV1().Roles("default").Create(context.Background(), role, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.RbacV1().Roles("default").Create(context.Background(), role2, metav1.CreateOptions{}) + _, err = c.k8sClient.RbacV1().Roles("default").Create(context.Background(), role2, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.RbacV1().Roles("default").Create(context.Background(), role3, metav1.CreateOptions{}) + _, err = c.k8sClient.RbacV1().Roles("default").Create(context.Background(), role3, metav1.CreateOptions{}) require.NoError(t, err) err = c.deleteRoles("consul", "default") require.NoError(t, err) - roles, err := c.kubernetes.RbacV1().Roles("default").List(context.Background(), metav1.ListOptions{}) + roles, err := c.k8sClient.RbacV1().Roles("default").List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) require.Len(t, roles.Items, 1) require.Equal(t, roles.Items[0].Name, role3.Name) @@ -217,7 +217,7 @@ func TestDeleteRoles(t *testing.T) { func TestDeleteRoleBindings(t *testing.T) { c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() rolebinding := &rbacv1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: "consul-test-role1", @@ -242,15 +242,15 @@ func TestDeleteRoleBindings(t *testing.T) { }, }, } - _, err := c.kubernetes.RbacV1().RoleBindings("default").Create(context.Background(), rolebinding, metav1.CreateOptions{}) + _, err := c.k8sClient.RbacV1().RoleBindings("default").Create(context.Background(), rolebinding, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.RbacV1().RoleBindings("default").Create(context.Background(), rolebinding2, metav1.CreateOptions{}) + _, err = c.k8sClient.RbacV1().RoleBindings("default").Create(context.Background(), rolebinding2, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.RbacV1().RoleBindings("default").Create(context.Background(), rolebinding3, metav1.CreateOptions{}) + _, err = c.k8sClient.RbacV1().RoleBindings("default").Create(context.Background(), rolebinding3, metav1.CreateOptions{}) require.NoError(t, err) err = c.deleteRoleBindings("consul", "default") require.NoError(t, err) - rolebindings, err := c.kubernetes.RbacV1().RoleBindings("default").List(context.Background(), metav1.ListOptions{}) + rolebindings, err := c.k8sClient.RbacV1().RoleBindings("default").List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) require.Len(t, rolebindings.Items, 1) require.Equal(t, rolebindings.Items[0].Name, rolebinding3.Name) @@ -258,7 +258,7 @@ func TestDeleteRoleBindings(t *testing.T) { func TestDeleteJobs(t *testing.T) { c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() job := &batchv1.Job{ ObjectMeta: metav1.ObjectMeta{ Name: "consul-test-job1", @@ -283,15 +283,15 @@ func TestDeleteJobs(t *testing.T) { }, }, } - _, err := c.kubernetes.BatchV1().Jobs("default").Create(context.Background(), job, metav1.CreateOptions{}) + _, err := c.k8sClient.BatchV1().Jobs("default").Create(context.Background(), job, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.BatchV1().Jobs("default").Create(context.Background(), job2, metav1.CreateOptions{}) + _, err = c.k8sClient.BatchV1().Jobs("default").Create(context.Background(), job2, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.BatchV1().Jobs("default").Create(context.Background(), job3, metav1.CreateOptions{}) + _, err = c.k8sClient.BatchV1().Jobs("default").Create(context.Background(), job3, metav1.CreateOptions{}) require.NoError(t, err) err = c.deleteJobs("consul", "default") require.NoError(t, err) - jobs, err := c.kubernetes.BatchV1().Jobs("default").List(context.Background(), metav1.ListOptions{}) + jobs, err := c.k8sClient.BatchV1().Jobs("default").List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) require.Len(t, jobs.Items, 1) require.Equal(t, jobs.Items[0].Name, job3.Name) @@ -299,7 +299,7 @@ func TestDeleteJobs(t *testing.T) { func TestDeleteClusterRoles(t *testing.T) { c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() clusterrole := &rbacv1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ Name: "consul-test-clusterrole1", @@ -324,15 +324,15 @@ func TestDeleteClusterRoles(t *testing.T) { }, }, } - _, err := c.kubernetes.RbacV1().ClusterRoles().Create(context.Background(), clusterrole, metav1.CreateOptions{}) + _, err := c.k8sClient.RbacV1().ClusterRoles().Create(context.Background(), clusterrole, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.RbacV1().ClusterRoles().Create(context.Background(), clusterrole2, metav1.CreateOptions{}) + _, err = c.k8sClient.RbacV1().ClusterRoles().Create(context.Background(), clusterrole2, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.RbacV1().ClusterRoles().Create(context.Background(), clusterrole3, metav1.CreateOptions{}) + _, err = c.k8sClient.RbacV1().ClusterRoles().Create(context.Background(), clusterrole3, metav1.CreateOptions{}) require.NoError(t, err) err = c.deleteClusterRoles("consul") require.NoError(t, err) - clusterroles, err := c.kubernetes.RbacV1().ClusterRoles().List(context.Background(), metav1.ListOptions{}) + clusterroles, err := c.k8sClient.RbacV1().ClusterRoles().List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) require.Len(t, clusterroles.Items, 1) require.Equal(t, clusterroles.Items[0].Name, clusterrole3.Name) @@ -340,7 +340,7 @@ func TestDeleteClusterRoles(t *testing.T) { func TestDeleteClusterRoleBindings(t *testing.T) { c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() clusterrolebinding := &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: "consul-test-clusterrolebinding1", @@ -365,15 +365,15 @@ func TestDeleteClusterRoleBindings(t *testing.T) { }, }, } - _, err := c.kubernetes.RbacV1().ClusterRoleBindings().Create(context.Background(), clusterrolebinding, metav1.CreateOptions{}) + _, err := c.k8sClient.RbacV1().ClusterRoleBindings().Create(context.Background(), clusterrolebinding, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.RbacV1().ClusterRoleBindings().Create(context.Background(), clusterrolebinding2, metav1.CreateOptions{}) + _, err = c.k8sClient.RbacV1().ClusterRoleBindings().Create(context.Background(), clusterrolebinding2, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.kubernetes.RbacV1().ClusterRoleBindings().Create(context.Background(), clusterrolebinding3, metav1.CreateOptions{}) + _, err = c.k8sClient.RbacV1().ClusterRoleBindings().Create(context.Background(), clusterrolebinding3, metav1.CreateOptions{}) require.NoError(t, err) err = c.deleteClusterRoleBindings("consul") require.NoError(t, err) - clusterrolebindings, err := c.kubernetes.RbacV1().ClusterRoleBindings().List(context.Background(), metav1.ListOptions{}) + clusterrolebindings, err := c.k8sClient.RbacV1().ClusterRoleBindings().List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) require.Len(t, clusterrolebindings.Items, 1) require.Equal(t, clusterrolebindings.Items[0].Name, clusterrolebinding3.Name) @@ -468,14 +468,14 @@ func TestFetchCustomResources(t *testing.T) { } c := getInitializedCommand(t, nil) - c.kubernetes = fake.NewSimpleClientset(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "other"}}) - c.apiext, c.dynamic = createClientsWithCrds() + c.k8sClient = fake.NewSimpleClientset(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "other"}}) + c.apiextK8sClient, c.dynamicK8sClient = createClientsWithCrds() - _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + _, err := c.dynamicK8sClient.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.dynamic.Resource(nonConsulGRV).Namespace("default").Create(context.Background(), &nonConsulCR1, metav1.CreateOptions{}) + _, err = c.dynamicK8sClient.Resource(nonConsulGRV).Namespace("default").Create(context.Background(), &nonConsulCR1, metav1.CreateOptions{}) require.NoError(t, err) - _, err = c.dynamic.Resource(nonConsulGRV).Namespace("other").Create(context.Background(), &nonConsulCR2, metav1.CreateOptions{}) + _, err = c.dynamicK8sClient.Resource(nonConsulGRV).Namespace("other").Create(context.Background(), &nonConsulCR2, metav1.CreateOptions{}) require.NoError(t, err) crds, err := c.fetchCustomResourceDefinitions() @@ -502,9 +502,9 @@ func TestDeleteCustomResources(t *testing.T) { } c := getInitializedCommand(t, nil) - c.apiext, c.dynamic = createClientsWithCrds() + c.apiextK8sClient, c.dynamicK8sClient = createClientsWithCrds() - _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + _, err := c.dynamicK8sClient.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) require.NoError(t, err) crds, err := c.fetchCustomResourceDefinitions() @@ -536,9 +536,9 @@ func TestPatchCustomResources(t *testing.T) { cr.SetFinalizers([]string{"consul.hashicorp.com"}) c := getInitializedCommand(t, nil) - c.apiext, c.dynamic = createClientsWithCrds() + c.apiextK8sClient, c.dynamicK8sClient = createClientsWithCrds() - _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + _, err := c.dynamicK8sClient.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) require.NoError(t, err) crds, err := c.fetchCustomResourceDefinitions() @@ -781,10 +781,10 @@ func TestUninstall(t *testing.T) { buf := new(bytes.Buffer) c := getInitializedCommand(t, buf) - c.kubernetes = fake.NewSimpleClientset() + c.k8sClient = fake.NewSimpleClientset() - c.apiext, c.dynamic = createClientsWithCrds() - _, err := c.dynamic.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) + c.apiextK8sClient, c.dynamicK8sClient = createClientsWithCrds() + _, err := c.dynamicK8sClient.Resource(serviceDefaultsGRV).Namespace("default").Create(context.Background(), &cr, metav1.CreateOptions{}) require.NoError(t, err) mock := tc.helmActionsRunner From 476e4a1cb04c333d616f96bd3fd3970ff9316e1f Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 12:44:04 -0400 Subject: [PATCH 33/43] Remove `IgnoreNotFoundError` --- cli/cmd/uninstall/uninstall.go | 2 +- cli/common/utils.go | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 45915ab4f2..dfb4451642 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -489,7 +489,7 @@ func (c *Command) deleteCustomResources(crs []unstructured.Unstructured, kindToR Resource(target). Namespace(cr.GetNamespace()). Delete(c.Ctx, cr.GetName(), metav1.DeleteOptions{}) - if common.IgnoreNotFoundError(err) != nil { + if err != nil && !k8serrors.IsNotFound(err) { return err } } diff --git a/cli/common/utils.go b/cli/common/utils.go index 95c56a7afb..b2e9714a9d 100644 --- a/cli/common/utils.go +++ b/cli/common/utils.go @@ -1,7 +1,6 @@ package common import ( - "k8s.io/apimachinery/pkg/api/errors" "os" "strings" ) @@ -82,12 +81,3 @@ func IsValidLabel(label string) bool { return true } - -// IgnoreNotFoundError is a convenience function which takes an error and will -// return it unless it represents a NotFound, 404 error. -func IgnoreNotFoundError(err error) error { - if statusError, ok := err.(*errors.StatusError); ok && statusError.ErrStatus.Code == 404 { - return nil - } - return err -} From b4d61a9599a5b653b1c1722dfc5b775414e9f43e Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 12:47:04 -0400 Subject: [PATCH 34/43] Match style guide on CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e2e4ced82..ea259f1101 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ FEATURES: IMPROVEMENTS: * CLI * Update minimum go version for project to 1.19 [[GH-1633](https://github.com/hashicorp/consul-k8s/pull/1633)] - * `consul-k8s uninstall` now deletes custom resources when uninstalling Consul. [[GH-1623](https://github.com/hashicorp/consul-k8s/pull/1623)] + * Enable `consul-k8s uninstall` to delete custom resources when uninstalling Consul. This is done by default. [[GH-1623](https://github.com/hashicorp/consul-k8s/pull/1623)] * Control Plane * Update minimum go version for project to 1.19 [[GH-1633](https://github.com/hashicorp/consul-k8s/pull/1633)] * Remove unneeded `agent:read` ACL permissions from mesh gateway policy. [[GH-1255](https://github.com/hashicorp/consul-k8s/pull/1255)] From 85695632c46fbd36af0a786151990657dffad47c Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 12:55:14 -0400 Subject: [PATCH 35/43] Use schema.ParseGroupVersion --- cli/cmd/uninstall/uninstall.go | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index dfb4451642..4c41abbd64 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -3,7 +3,6 @@ package uninstall import ( "fmt" "os" - "strings" "sync" "time" @@ -473,19 +472,18 @@ func (c *Command) fetchCustomResources(crds *apiextv1.CustomResourceDefinitionLi // sends a request to each one to be deleted. func (c *Command) deleteCustomResources(crs []unstructured.Unstructured, kindToResource map[string]string) error { for _, cr := range crs { - apiVersion := strings.Split(cr.GetAPIVersion(), "/") - group, version := apiVersion[0], apiVersion[1] - if group == "" || version == "" { - return fmt.Errorf("malformed api version: %s", apiVersion) + gv, err := schema.ParseGroupVersion(cr.GetAPIVersion()) + if err != nil { + return err } target := schema.GroupVersionResource{ - Group: group, - Version: version, + Group: gv.Group, + Version: gv.Version, Resource: kindToResource[cr.GetKind()], } - err := c.dynamicK8sClient. + err = c.dynamicK8sClient. Resource(target). Namespace(cr.GetNamespace()). Delete(c.Ctx, cr.GetName(), metav1.DeleteOptions{}) @@ -507,19 +505,18 @@ func (c *Command) patchCustomResources(crs []unstructured.Unstructured, kindToRe }]`) for _, cr := range crs { - apiVersion := strings.Split(cr.GetAPIVersion(), "/") - group, version := apiVersion[0], apiVersion[1] - if group == "" || version == "" { - return fmt.Errorf("malformed api version: %s", apiVersion) + gv, err := schema.ParseGroupVersion(cr.GetAPIVersion()) + if err != nil { + return err } target := schema.GroupVersionResource{ - Group: group, - Version: version, + Group: gv.Group, + Version: gv.Version, Resource: kindToResource[cr.GetKind()], } - _, err := c.dynamicK8sClient. + _, err = c.dynamicK8sClient. Resource(target). Namespace(cr.GetNamespace()). Patch(c.Ctx, cr.GetName(), types.JSONPatchType, finalizerPatch, metav1.PatchOptions{}) From 07d535f40b5af0eab7b841f3a3eb406179acc48a Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 13:31:43 -0400 Subject: [PATCH 36/43] Fix punctuation on initKubernetes --- cli/cmd/uninstall/uninstall.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 4c41abbd64..02e3048e45 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -314,7 +314,7 @@ func (c *Command) Run(args []string) int { return 0 } -// initKubernetes sets up the kubernetes clients to use for non Helm SDK calls to the Kubernetes API +// initKubernetes sets up the kubernetes clients to use for non Helm SDK calls to the Kubernetes API. // The Helm SDK will use settings.RESTClientGetter for its calls as well, so this will // use a consistent method to target the right cluster for both Helm SDK and non Helm SDK calls. func (c *Command) initKubernetes(settings *helmCLI.EnvSettings) error { From 0d47724c12514fcecd21a14498399b569b83e57b Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 13:52:17 -0400 Subject: [PATCH 37/43] Improve logging and separate out removal of CRs --- cli/cmd/uninstall/uninstall.go | 103 +++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 44 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 02e3048e45..23bc68e1fb 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -371,48 +371,7 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // Delete any custom resources managed by Consul. If they cannot be deleted, // patch the finalizers to be empty on each one. if releaseType == common.ReleaseTypeConsul { - uiLogger("Deleting custom resources managed by Consul") - crds, err := c.fetchCustomResourceDefinitions() - if err != nil { - return fmt.Errorf("unable to fetch Custom Resource Definitions for Consul deployment: %v", err) - } - kindToResource := mapCRKindToResourceName(crds) - err = backoff.Retry(func() error { - crs, err := c.fetchCustomResources(crds) - if err != nil { - return err - } - if len(crs) == 0 { - return nil - } - - if err = c.deleteCustomResources(crs, kindToResource); err != nil { - return err - } - - crs, err = c.fetchCustomResources(crds) - if err != nil { - return err - } - if len(crs) != 0 { - return common.NewDeletionError(fmt.Sprintf("%d custom resources remain after deletion request. Retrying deletion", len(crs))) - } - - return nil - }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) - if common.IsDeletionError(err) { - uiLogger("Patching finalizers on custom resources managed by Consul") - crs, err := c.fetchCustomResources(crds) - if err != nil { - return err - } - - if err = c.patchCustomResources(crs, kindToResource); err != nil { - return err - } - } else if err != nil { - return err - } + c.removeCustomResources(uiLogger) } actionConfig, err := helm.InitActionConfig(actionConfig, namespace, settings, uiLogger) @@ -436,6 +395,60 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil } +func (c *Command) removeCustomResources(uiLogger action.DebugLog) error { + uiLogger("Deleting custom resources managed by Consul") + + crds, err := c.fetchCustomResourceDefinitions() + if err != nil { + return fmt.Errorf("unable to fetch Custom Resource Definitions for Consul deployment: %v", err) + } + kindToResource := mapCRKindToResourceName(crds) + + crs, err := c.fetchCustomResources(crds) + if err != nil { + return err + } + if err = c.deleteCustomResources(crs, kindToResource, uiLogger); err != nil { + return err + } + + err = backoff.Retry(func() error { + crs, err := c.fetchCustomResources(crds) + if err != nil { + return err + } + if len(crs) != 0 { + return common.NewDeletionError(fmt.Sprintf("%d custom resources remain after deletion request. Retrying deletion", len(crs))) + } + return nil + }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) + if common.IsDeletionError(err) { + uiLogger("Patching finalizers on custom resources managed by Consul") + + crs, err := c.fetchCustomResources(crds) + if err != nil { + return err + } + + if err = c.patchCustomResources(crs, kindToResource, uiLogger); err != nil { + return err + } + + crs, err = c.fetchCustomResources(crds) + if err != nil { + return err + } + + if len(crs) != 0 { + c.UI.Output("Unable to remove all custom resources managed by Consul. %d custom resources remain and will need to be removed manually.", len(crs), terminal.WithErrorStyle()) + } + } else if err != nil { + return err + } + + return nil +} + // fetchCustomResourceDefinitions fetches all Custom Resource Definitions managed by Consul. func (c *Command) fetchCustomResourceDefinitions() (*apiextv1.CustomResourceDefinitionList, error) { return c.apiextK8sClient.ApiextensionsV1().CustomResourceDefinitions().List(c.Ctx, metav1.ListOptions{ @@ -470,7 +483,7 @@ func (c *Command) fetchCustomResources(crds *apiextv1.CustomResourceDefinitionLi // deleteCustomResources takes a list of unstructured custom resources and // sends a request to each one to be deleted. -func (c *Command) deleteCustomResources(crs []unstructured.Unstructured, kindToResource map[string]string) error { +func (c *Command) deleteCustomResources(crs []unstructured.Unstructured, kindToResource map[string]string, uiLogger action.DebugLog) error { for _, cr := range crs { gv, err := schema.ParseGroupVersion(cr.GetAPIVersion()) if err != nil { @@ -483,6 +496,7 @@ func (c *Command) deleteCustomResources(crs []unstructured.Unstructured, kindToR Resource: kindToResource[cr.GetKind()], } + uiLogger(fmt.Sprintf("Starting delete for \"%s\" %s", cr.GetName(), cr.GetKind())) err = c.dynamicK8sClient. Resource(target). Namespace(cr.GetNamespace()). @@ -497,7 +511,7 @@ func (c *Command) deleteCustomResources(crs []unstructured.Unstructured, kindToR // patchCustomResources takes a list of unstructured custom resources and // sends a request to each one to patch its finalizers to an empty list. -func (c *Command) patchCustomResources(crs []unstructured.Unstructured, kindToResource map[string]string) error { +func (c *Command) patchCustomResources(crs []unstructured.Unstructured, kindToResource map[string]string, uiLogger action.DebugLog) error { finalizerPatch := []byte(`[{ "op": "replace", "path": "/metadata/finalizers", @@ -516,6 +530,7 @@ func (c *Command) patchCustomResources(crs []unstructured.Unstructured, kindToRe Resource: kindToResource[cr.GetKind()], } + uiLogger(fmt.Sprintf("Patching finalizers for \"%s\" %s", cr.GetName(), cr.GetKind())) _, err = c.dynamicK8sClient. Resource(target). Namespace(cr.GetNamespace()). From 3b3c03441c486b5fb604655a89f1bad6cf35478d Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 14:11:48 -0400 Subject: [PATCH 38/43] Clean up the CR deletion method a bit --- cli/cmd/uninstall/uninstall.go | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 23bc68e1fb..ec2c11cfac 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -371,7 +371,9 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin // Delete any custom resources managed by Consul. If they cannot be deleted, // patch the finalizers to be empty on each one. if releaseType == common.ReleaseTypeConsul { - c.removeCustomResources(uiLogger) + if err := c.removeCustomResources(uiLogger); err != nil { + c.UI.Output("Error removing custom resources: %v", err.Error(), terminal.WithErrorStyle()) + } } actionConfig, err := helm.InitActionConfig(actionConfig, namespace, settings, uiLogger) @@ -408,6 +410,7 @@ func (c *Command) removeCustomResources(uiLogger action.DebugLog) error { if err != nil { return err } + if err = c.deleteCustomResources(crs, kindToResource, uiLogger); err != nil { return err } @@ -422,29 +425,29 @@ func (c *Command) removeCustomResources(uiLogger action.DebugLog) error { } return nil }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) - if common.IsDeletionError(err) { - uiLogger("Patching finalizers on custom resources managed by Consul") + if !common.IsDeletionError(err) { + return err + } - crs, err := c.fetchCustomResources(crds) - if err != nil { - return err - } + // Custom resources could not be deleted directly, attempt to patch their finalizers to an empty array. + uiLogger("Patching finalizers on custom resources managed by Consul") - if err = c.patchCustomResources(crs, kindToResource, uiLogger); err != nil { - return err - } + crs, err = c.fetchCustomResources(crds) + if err != nil { + return err + } - crs, err = c.fetchCustomResources(crds) - if err != nil { - return err - } + if err = c.patchCustomResources(crs, kindToResource, uiLogger); err != nil { + return err + } - if len(crs) != 0 { - c.UI.Output("Unable to remove all custom resources managed by Consul. %d custom resources remain and will need to be removed manually.", len(crs), terminal.WithErrorStyle()) - } - } else if err != nil { + crs, err = c.fetchCustomResources(crds) + if err != nil { return err } + if len(crs) != 0 { + return fmt.Errorf("unable to remove all custom resources managed by Consul. %d custom resources remain and will need to be removed manually", len(crs)) + } return nil } From 2073acd7429a2870a80db5b796d69f517a447770 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 14:14:00 -0400 Subject: [PATCH 39/43] Order imports --- cli/cmd/uninstall/uninstall.go | 4 +--- cli/cmd/uninstall/uninstall_test.go | 11 +++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index ec2c11cfac..41afaa58b6 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -6,14 +6,11 @@ import ( "sync" "time" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - "github.com/cenkalti/backoff" "github.com/hashicorp/consul-k8s/cli/common" "github.com/hashicorp/consul-k8s/cli/common/flag" "github.com/hashicorp/consul-k8s/cli/common/terminal" "github.com/hashicorp/consul-k8s/cli/helm" - "github.com/posener/complete" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -21,6 +18,7 @@ import ( helmCLI "helm.sh/helm/v3/pkg/cli" apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index e770363bfb..1d84db3ce3 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -10,12 +10,6 @@ import ( "os" "testing" - apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/kubernetes/fake" - "github.com/hashicorp/consul-k8s/cli/common" cmnFlag "github.com/hashicorp/consul-k8s/cli/common/flag" "github.com/hashicorp/consul-k8s/cli/common/terminal" @@ -30,10 +24,15 @@ import ( v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apiextFake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" dynamicFake "k8s.io/client-go/dynamic/fake" + "k8s.io/client-go/kubernetes/fake" ) var ( From 63aaf5b2faaf5852f1b95aacee0a7810be9b3b95 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 14:18:42 -0400 Subject: [PATCH 40/43] Add doc comment to removeCustomResources --- cli/cmd/uninstall/uninstall.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 41afaa58b6..80ce278af2 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -395,6 +395,10 @@ func (c *Command) uninstallHelmRelease(releaseName, namespace, releaseType strin return nil } +// removeCustomResources fetches a list of custom resource defintions managed +// by Consul and attempts to delete every custom resource for each definition. +// If the resources cannot be deleted directly, the finalizers on each resource +// are patched to be an empty list, freeing them to be deleted by Kubernetes. func (c *Command) removeCustomResources(uiLogger action.DebugLog) error { uiLogger("Deleting custom resources managed by Consul") From 8c02cf2dd90c120fa668dbd1dc16f2cf031eadd2 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 15:07:54 -0400 Subject: [PATCH 41/43] Add fakeUILogger --- cli/cmd/uninstall/uninstall_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index 1d84db3ce3..de9188c182 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -513,7 +513,7 @@ func TestDeleteCustomResources(t *testing.T) { require.NoError(t, err) require.Len(t, actual, 1) - err = c.deleteCustomResources([]unstructured.Unstructured{cr}, mapCRKindToResourceName(crds)) + err = c.deleteCustomResources([]unstructured.Unstructured{cr}, mapCRKindToResourceName(crds), fakeUILogger) require.NoError(t, err) actual, err = c.fetchCustomResources(crds) @@ -543,7 +543,7 @@ func TestPatchCustomResources(t *testing.T) { crds, err := c.fetchCustomResourceDefinitions() require.NoError(t, err) - err = c.patchCustomResources([]unstructured.Unstructured{cr}, mapCRKindToResourceName(crds)) + err = c.patchCustomResources([]unstructured.Unstructured{cr}, mapCRKindToResourceName(crds), fakeUILogger) require.NoError(t, err) actual, err := c.fetchCustomResources(crds) @@ -868,3 +868,5 @@ func createClientsWithCrds() (apiext.Interface, dynamic.Interface) { } return apiextFake.NewSimpleClientset(&crds), dynamicFake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), grvToListKind) } + +func fakeUILogger(s string, i ...interface{}) {} From 168450c404f0bda15dec6ff429cba7a21c14eebb Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 1 Nov 2022 18:58:05 -0400 Subject: [PATCH 42/43] Add retry to verifying patch command --- cli/cmd/uninstall/uninstall.go | 20 +++++++++++++------- cli/common/error.go | 25 +++++++++++++------------ 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/cli/cmd/uninstall/uninstall.go b/cli/cmd/uninstall/uninstall.go index 80ce278af2..8431008754 100644 --- a/cli/cmd/uninstall/uninstall.go +++ b/cli/cmd/uninstall/uninstall.go @@ -423,11 +423,11 @@ func (c *Command) removeCustomResources(uiLogger action.DebugLog) error { return err } if len(crs) != 0 { - return common.NewDeletionError(fmt.Sprintf("%d custom resources remain after deletion request. Retrying deletion", len(crs))) + return common.NewDanglingResourceError(fmt.Sprintf("%d custom resources remain after deletion request", len(crs))) } return nil }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) - if !common.IsDeletionError(err) { + if !common.IsDanglingResourceError(err) { return err } @@ -443,12 +443,18 @@ func (c *Command) removeCustomResources(uiLogger action.DebugLog) error { return err } - crs, err = c.fetchCustomResources(crds) + err = backoff.Retry(func() error { + crs, err := c.fetchCustomResources(crds) + if err != nil { + return err + } + if len(crs) != 0 { + return common.NewDanglingResourceError(fmt.Sprintf("%d custom resources remain after request to patch finalizers", len(crs))) + } + return nil + }, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 5)) if err != nil { - return err - } - if len(crs) != 0 { - return fmt.Errorf("unable to remove all custom resources managed by Consul. %d custom resources remain and will need to be removed manually", len(crs)) + return fmt.Errorf("unable to remove all custom resources managed by Consul. %d custom resources remain and will need to be removed manually. %v", len(crs), err) } return nil diff --git a/cli/common/error.go b/cli/common/error.go index 7901e09b56..3d8e3deb51 100644 --- a/cli/common/error.go +++ b/cli/common/error.go @@ -1,24 +1,25 @@ package common -// DeletionError should be used when a request was made to delete a resource -// and that request failed. -type DeletionError struct { +// DanglingResourceError should be used when a request was made to remove +// a resource and the resource still remains after enough time has elapsed +// that it should have been removed by Kubernetes. +type DanglingResourceError struct { message string } -// NewDeletionError returns a new instance of DeletionError for handling -// failures in deletion requests. -func NewDeletionError(message string) *DeletionError { - return &DeletionError{message} +// NewDanglingResourceError returns a new instance of DanglingResourceError with +// the given message. +func NewDanglingResourceError(message string) *DanglingResourceError { + return &DanglingResourceError{message} } -// Error returns a string representation of the deletion error. -func (d *DeletionError) Error() string { +// Error returns a string representation of the dangling resource error. +func (d *DanglingResourceError) Error() string { return d.message } -// IsDeletionError returns true if the error passed in is of type DeletionError. -func IsDeletionError(err error) bool { - _, ok := err.(*DeletionError) +// IsDanglingResourceError returns true if the error passed in is of type DanglingResourceError. +func IsDanglingResourceError(err error) bool { + _, ok := err.(*DanglingResourceError) return ok } From 2be231a84f9e1deddbdb36da1fab263f707d4833 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 2 Nov 2022 12:29:51 -0400 Subject: [PATCH 43/43] Fix output in uninstall test --- cli/cmd/uninstall/uninstall_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/cmd/uninstall/uninstall_test.go b/cli/cmd/uninstall/uninstall_test.go index de9188c182..b8fd823d3e 100644 --- a/cli/cmd/uninstall/uninstall_test.go +++ b/cli/cmd/uninstall/uninstall_test.go @@ -623,7 +623,7 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n --> Starting delete for \"server\" ServiceDefaults\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -667,7 +667,7 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ✓ Successfully uninstalled Consul Helm release.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n --> Starting delete for \"server\" ServiceDefaults\n ✓ Successfully uninstalled Consul Helm release.\n", "\n==> Other Consul Resources\n Deleting data for installation: \n Name: consul\n Namespace consul\n ✓ No PVCs found.\n ✓ No Consul secrets found.\n ✓ No Consul service accounts found.\n ✓ No Consul roles found.\n ✓ No Consul rolebindings found.\n ✓ No Consul jobs found.\n ✓ No Consul cluster roles found.\n ✓ No Consul cluster role bindings found.\n", }, helmActionsRunner: &helm.MockActionRunner{ @@ -691,7 +691,7 @@ func TestUninstall(t *testing.T) { "\n==> Checking if Consul demo application can be uninstalled\n ✓ Existing Consul demo application installation found.\n", "\n==> Consul Demo Application Uninstall Summary\n Name: consul-demo\n Namespace: consul-demo\n ✓ Successfully uninstalled Consul demo application Helm release.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n --> Starting delete for \"server\" ServiceDefaults\n ✓ Successfully uninstalled Consul Helm release.\n ✓ Skipping deleting PVCs, secrets, and service accounts.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) { @@ -713,7 +713,7 @@ func TestUninstall(t *testing.T) { messages: []string{ "\n==> Checking if Consul demo application can be uninstalled\n No existing Consul demo application installation found.\n", "\n==> Checking if Consul can be uninstalled\n ✓ Existing Consul installation found.\n", - "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n ! Helm returned an error.\n", + "\n==> Consul Uninstall Summary\n Name: consul\n Namespace: consul\n --> Deleting custom resources managed by Consul\n --> Starting delete for \"server\" ServiceDefaults\n ! Helm returned an error.\n", }, helmActionsRunner: &helm.MockActionRunner{ CheckForInstallationsFunc: func(options *helm.CheckForInstallationsOptions) (bool, string, string, error) {