Introduce KRM based k8s applier
The KRM based k8s applier solves multiple design problems which were introduced in previous airshipctl generation, making apply code and process more clear, reliable and readable. In particular: * k8s applier now is a KRM function and it allows the end user to choose or implement desired backend for k8s apply operations; * the related amount of code was reduced by three times, multiple unused and unnecessary structs/interfaces/design patterns were removed or rewrited in more clean and efficient way; * removed cli-utils dependency from airshipctl; * fixed several bugs and code issues, such as incorrect printing of tables, duplicated unit tests, improper generation and applying inventory config map, etc; * cli-utils version used in KRM function was bumped to 0.26.0; * phases with duplicated k8s resources were removed or fixed; * unit test coverage increased to 83.1%; * KRM function logs were integrated with klog library which allows to observe logs directly from cli-utils and other dependent libs. Change-Id: Ief509f1d6abefd53caf7fcffc4e36b0319815373 Signed-off-by: Ruslan Aliev <raliev@mirantis.com> Closes: #646
This commit is contained in:
parent
55f04e7394
commit
3e44c42989
1
Makefile
1
Makefile
@ -119,6 +119,7 @@ docker-image_DOCKERFILE:=Dockerfile
|
||||
# kubeval-validator, toolbox and toolbox-virsh don't depend on
|
||||
# airshipctl repo. Their Dockerfiles don't
|
||||
# need to be called from the root of the repo.
|
||||
applier_IS_INDEPENDED:=true
|
||||
kubeval-validator_IS_INDEPENDED:=true
|
||||
clusterctl_IS_INDEPENDED:=true
|
||||
clusterctl-v0.3_IS_INDEPENDED:=true
|
||||
|
@ -31,7 +31,7 @@ func NewVersionCommand() *cobra.Command {
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
out := cmd.OutOrStdout()
|
||||
clientV := clientVersion()
|
||||
w := util.NewTabWriter(out)
|
||||
w := util.GetNewTabWriter(out)
|
||||
defer w.Flush()
|
||||
fmt.Fprintf(w, "%s:\t%s\n", "airshipctl", clientV)
|
||||
},
|
||||
|
3
go.mod
3
go.mod
@ -7,7 +7,6 @@ require (
|
||||
github.com/Microsoft/go-winio v0.4.14 // indirect
|
||||
github.com/ahmetalpbalkan/dlog v0.0.0-20170105205344-4fb5f8204f26 // indirect
|
||||
github.com/ahmetb/dlog v0.0.0-20170105205344-4fb5f8204f26
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
|
||||
github.com/containerd/containerd v1.4.1 // indirect
|
||||
github.com/docker/docker v20.10.5+incompatible
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
@ -17,6 +16,7 @@ require (
|
||||
github.com/go-git/go-git/v5 v5.0.0
|
||||
github.com/gorilla/mux v1.7.4 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
|
||||
github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
@ -34,7 +34,6 @@ require (
|
||||
k8s.io/kubectl v0.21.1
|
||||
opendev.org/airship/go-redfish v0.0.0-20211004183611-3c3d7c6ba009
|
||||
opendev.org/airship/go-redfish/client v0.0.0-20211004183611-3c3d7c6ba009
|
||||
sigs.k8s.io/cli-utils v0.21.1
|
||||
sigs.k8s.io/controller-runtime v0.8.3
|
||||
sigs.k8s.io/kustomize/api v0.8.11
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0
|
||||
|
112
go.sum
112
go.sum
@ -33,31 +33,23 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
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.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||
github.com/Azure/go-autorest/autorest v0.11.12 h1:gI8ytXbxMfI+IVbI9mP2JGCTXIuhHLgRlvQ9X4PsnHE=
|
||||
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5 h1:Y3bBUV4rTuxenJJs41HU3qmqsb+auo+a3Lz+PlJPpL0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
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.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
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/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8Pcx+3oqrE=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@ -75,12 +67,9 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB
|
||||
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/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
@ -95,7 +84,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
@ -111,14 +99,12 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
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/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
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/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
|
||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 h1:HD4PLRzjuCVW79mQ0/pdsalOLHJ+FaEoqJLxfltpb2U=
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@ -130,17 +116,13 @@ github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
@ -155,7 +137,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.5+incompatible h1:o5WL5onN4awYGwrW7+oTn5x9AF2prw7V0Ox8ZEkoCdg=
|
||||
github.com/docker/docker v20.10.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
@ -167,7 +148,6 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs=
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
@ -179,7 +159,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
|
||||
@ -194,6 +173,7 @@ github.com/form3tech-oss/jwt-go v3.2.2+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 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE=
|
||||
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@ -223,8 +203,6 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
|
||||
github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
||||
github.com/go-logr/zapr v0.2.0 h1:v6Ji8yBW77pva6NkJKQdHLAJKrIJKRHz0RXwPqCHSR4=
|
||||
github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU=
|
||||
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=
|
||||
@ -234,13 +212,11 @@ github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2
|
||||
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
@ -254,7 +230,6 @@ github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCs
|
||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
|
||||
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||
@ -266,7 +241,6 @@ github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pL
|
||||
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
|
||||
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
||||
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
@ -274,7 +248,6 @@ github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tF
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
||||
@ -297,7 +270,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@ -313,8 +285,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
@ -349,13 +319,9 @@ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
@ -397,7 +363,6 @@ github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs
|
||||
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
@ -406,11 +371,9 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
@ -440,7 +403,6 @@ github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb h1:w1g9wNDIE/pHS
|
||||
github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
@ -482,7 +444,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
@ -502,23 +463,19 @@ 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.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
||||
github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
|
||||
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
|
||||
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
@ -549,7 +506,6 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
@ -557,7 +513,6 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
@ -582,7 +537,6 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
||||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
@ -592,7 +546,6 @@ github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||
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.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
@ -601,7 +554,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
@ -613,13 +565,11 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
|
||||
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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
@ -630,7 +580,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||
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=
|
||||
@ -640,26 +589,20 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
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.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
|
||||
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
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-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -668,7 +611,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@ -706,8 +648,6 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -731,7 +671,6 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@ -768,7 +707,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -776,8 +714,6 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
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-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -795,7 +731,6 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -814,7 +749,6 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -830,7 +764,6 @@ golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXR
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -848,7 +781,6 @@ golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiT
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -868,7 +800,6 @@ golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@ -909,7 +840,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
|
||||
gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
|
||||
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=
|
||||
@ -970,7 +900,6 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
@ -1020,7 +949,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@ -1036,73 +964,47 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
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.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
|
||||
k8s.io/api v0.18.10/go.mod h1:xWtwPX1v47j5RTncmlMFGCx8b0avh+nP8OgZZ9hjo3M=
|
||||
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
||||
k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8=
|
||||
k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c=
|
||||
k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
|
||||
k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY=
|
||||
k8s.io/apiextensions-apiserver v0.18.10/go.mod h1:XOE93YaGrb8Pa+ro00Jx3fhzRJ7UB0bU37jRTQXpTOM=
|
||||
k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk=
|
||||
k8s.io/apiextensions-apiserver v0.21.1 h1:AA+cnsb6w7SZ1vD32Z+zdgfXdXY8X9uGX5bN6EoPEIo=
|
||||
k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA=
|
||||
k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
|
||||
k8s.io/apimachinery v0.18.10/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk=
|
||||
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs=
|
||||
k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
|
||||
k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
|
||||
k8s.io/apiserver v0.18.10/go.mod h1:N4FaJo9BeSgmtvVByXi4fPSQPRqhvvLMGqswwkddob8=
|
||||
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
||||
k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY=
|
||||
k8s.io/cli-runtime v0.18.10/go.mod h1:8awhtXxYzOsxCrxgMTmR3DkIV8M/Gcu/v1aCIzQKIV4=
|
||||
k8s.io/cli-runtime v0.21.1 h1:Oj/iZxa7LLXrhzShaLNF4rFJEIEBTDHj0dJw4ra2vX4=
|
||||
k8s.io/cli-runtime v0.21.1/go.mod h1:TI9Bvl8lQWZB2KqE91QLCp9AZE4l29zNFnj/x4IX4Fw=
|
||||
k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
|
||||
k8s.io/client-go v0.18.10/go.mod h1:XBkFAqPrzqfwmGkV5ac+mlgBpWcz5TkhLw2808q8C3c=
|
||||
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
||||
k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE=
|
||||
k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4=
|
||||
k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs=
|
||||
k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
|
||||
k8s.io/code-generator v0.18.10/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
|
||||
k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
|
||||
k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q=
|
||||
k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
|
||||
k8s.io/component-base v0.18.10/go.mod h1:ZzFXjzUBHKOcF0mnWkxBI1wDu5t+CV3GxXKKvHZBLf0=
|
||||
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
||||
k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0=
|
||||
k8s.io/component-base v0.21.1 h1:iLpj2btXbR326s/xNQWmPNGu0gaYSjzn7IN/5i28nQw=
|
||||
k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA=
|
||||
k8s.io/component-helpers v0.21.1/go.mod h1:FtC1flbiQlosHQrLrRUulnKxE4ajgWCGy/67fT2GRlQ=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/klog/v2 v2.0.0/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.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts=
|
||||
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
|
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||
k8s.io/kubectl v0.18.10/go.mod h1:VVVSZir1jxZ2t8q6UGp6c+j5Uo3/bce9gL/Qcf67g08=
|
||||
k8s.io/kubectl v0.21.1 h1:ySEusoeSgSDSiSBncDMsNrthSa3OSlXqT4R2rf1VFTw=
|
||||
k8s.io/kubectl v0.21.1/go.mod h1:PMYR88MqESuysBM/MX+Vu4JbX/50nY4d4kny+SPEI2U=
|
||||
k8s.io/metrics v0.18.10/go.mod h1:7FQ0/pv0J15/kp8s8WvaeU6tz6jzAKk+xh1eHGwiaW8=
|
||||
k8s.io/metrics v0.21.1/go.mod h1:pyDVLsLe++FIGDBFU80NcW4xMFsuiVTWL8Zfi7+PpNo=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009 h1:0T5IaWHO3sJTEmCP6mUlBvMukxPKUQWqiI/YuiBNMiQ=
|
||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
@ -1114,31 +1016,21 @@ opendev.org/airship/go-redfish/client v0.0.0-20211004183611-3c3d7c6ba009/go.mod
|
||||
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.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/cli-utils v0.21.1 h1:cDNLRGvVshr9XjpaP0PghMXUQOLB4QFtZC+/YTGiWyw=
|
||||
sigs.k8s.io/cli-utils v0.21.1/go.mod h1:Mt1gLc/Nfa7Z3Lhbfk72uT2Kc4GNyuX4oMqEN9FbPMs=
|
||||
sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo=
|
||||
sigs.k8s.io/controller-runtime v0.8.3 h1:GMHvzjTmaWHQB8HadW+dIvBoJuLvZObYJ5YoZruPRao=
|
||||
sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||
sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY=
|
||||
sigs.k8s.io/kustomize/api v0.8.11 h1:LzQzlq6Z023b+mBtc6v72N2mSHYmN8x7ssgbf/hv0H8=
|
||||
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
|
||||
sigs.k8s.io/kustomize/cmd/config v0.9.10/go.mod h1:Mrby0WnRH7hA6OwOYnYpfpiY0WJIMgYrEDfwOeFdMK0=
|
||||
sigs.k8s.io/kustomize/kustomize/v4 v4.1.2/go.mod h1:PxBvo4WGYlCLeRPL+ziT64wBXqbgfcalOS/SXa/tcyo=
|
||||
sigs.k8s.io/kustomize/kyaml v0.9.4/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
|
||||
sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg=
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0 h1:9KhiCPKaVyuPcgOLJXkvytOvjMJLoxpjodiycb4gHsA=
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
|
||||
|
31
krm-functions/applier/Dockerfile
Normal file
31
krm-functions/applier/Dockerfile
Normal file
@ -0,0 +1,31 @@
|
||||
ARG GO_IMAGE=quay.io/airshipit/golang:1.16.8-buster
|
||||
ARG PLUGINS_RELEASE_IMAGE=quay.io/airshipit/alpine:3.13.5
|
||||
|
||||
FROM ${GO_IMAGE} as function
|
||||
ARG GOPROXY=""
|
||||
# Inject custom root certificate authorities if needed
|
||||
# Docker does not have a good conditional copy statement and requires that a source file exists
|
||||
# to complete the copy function without error. Therefore the README.md file will be copied to
|
||||
# the image every time even if there are no .crt files.
|
||||
COPY ./certs/* /usr/local/share/ca-certificates/
|
||||
RUN update-ca-certificates
|
||||
ENV PATH "/usr/local/go/bin:$PATH"
|
||||
ENV CGO_ENABLED=0
|
||||
WORKDIR /go/src/
|
||||
COPY image/ .
|
||||
RUN go mod download
|
||||
RUN go build -v -o /usr/local/bin/config-function ./
|
||||
|
||||
FROM ${PLUGINS_RELEASE_IMAGE} as release
|
||||
# Inject custom root certificate authorities if needed
|
||||
# Docker does not have a good conditional copy statement and requires that a source file exists
|
||||
# to complete the copy function without error. Therefore the README.md file will be copied to
|
||||
# the image every time even if there are no .crt files.
|
||||
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
|
||||
COPY ./certs/* /usr/local/share/ca-certificates/
|
||||
RUN update-ca-certificates
|
||||
COPY --from=function /usr/local/bin/config-function /usr/local/bin/config-function
|
||||
ENV HOME=/home/applier
|
||||
WORKDIR $HOME
|
||||
RUN chmod -R a+w $HOME
|
||||
CMD ["config-function"]
|
22
krm-functions/applier/README.md
Normal file
22
krm-functions/applier/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Applier
|
||||
|
||||
This is a KRM function which applies resources to k8s using
|
||||
[cli-utils](https://github.com/kubernetes-sigs/cli-utils)
|
||||
with appropriate options.
|
||||
|
||||
## Function implementation
|
||||
|
||||
The function is implemented as an [image](image), and built using `make docker-image-applier`.
|
||||
|
||||
### Function configuration
|
||||
|
||||
As input options, the KRM function receives a struct with apply options.
|
||||
See the `ApplyConfig` struct definition in v1alpha1 airshipctl API for the documentation.
|
||||
|
||||
## Function invocation
|
||||
|
||||
The function invoked by airshipctl command via `airshipctl phase run`:
|
||||
|
||||
airshipctl phase run <phase_name>
|
||||
|
||||
if appropriate phase has k8s_apply executor defined.
|
6
krm-functions/applier/certs/README.md
Normal file
6
krm-functions/applier/certs/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Additional Docker image root certificate authorities
|
||||
If you require additional certificate authorities for your Docker image:
|
||||
* Add ASCII PEM encoded .crt files to this directory
|
||||
* The files will be copied into your docker image at build time.
|
||||
|
||||
To update manually copy the .crt files to /usr/local/share/ca-certificates/ and run sudo update-ca-certificates.
|
19
krm-functions/applier/image/go.mod
Normal file
19
krm-functions/applier/image/go.mod
Normal file
@ -0,0 +1,19 @@
|
||||
module opendev.org/airship/airshipctl/krm-functions/applier/image
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
|
||||
k8s.io/api v0.21.1
|
||||
k8s.io/apimachinery v0.21.1
|
||||
k8s.io/cli-runtime v0.21.1
|
||||
k8s.io/client-go v0.21.1
|
||||
k8s.io/klog/v2 v2.9.0
|
||||
k8s.io/kubectl v0.21.1
|
||||
sigs.k8s.io/cli-utils v0.26.0
|
||||
sigs.k8s.io/controller-runtime v0.9.0-beta.5.0.20210524185538-7181f1162e79
|
||||
sigs.k8s.io/kustomize/api v0.8.11 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0
|
||||
)
|
981
krm-functions/applier/image/go.sum
Normal file
981
krm-functions/applier/image/go.sum
Normal file
@ -0,0 +1,981 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
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/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
|
||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
|
||||
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=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
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/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
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/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
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/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 h1:HD4PLRzjuCVW79mQ0/pdsalOLHJ+FaEoqJLxfltpb2U=
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs=
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
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=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
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/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
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=
|
||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
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 v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM=
|
||||
github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
||||
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
||||
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
|
||||
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
|
||||
github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
|
||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
|
||||
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
|
||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw=
|
||||
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
|
||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
|
||||
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
||||
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
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/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/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.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-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 h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q=
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/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.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
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.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
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/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
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=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
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/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
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 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
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/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
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/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134=
|
||||
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.12.0 h1:p4oGGk2M2UJc0wWN4lHFvIB71lxsh0T/UiKCCgFADY8=
|
||||
github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
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/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
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-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
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.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
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.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
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/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
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/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/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.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spyzhov/ajson v0.4.2 h1:JMByd/jZApPKDvNsmO90X2WWGbmT2ahDFp73QhZbg3s=
|
||||
github.com/spyzhov/ajson v0.4.2/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzyqMuVA=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||
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.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
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.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
|
||||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
||||
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=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-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-20190125091013-d26f9f9a57f3/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=
|
||||
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
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=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
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/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-20181122145206-62eef0e2fa9b/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/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-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-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/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=
|
||||
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/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
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=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
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=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
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/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
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/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/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c=
|
||||
k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
|
||||
k8s.io/apiextensions-apiserver v0.21.1 h1:AA+cnsb6w7SZ1vD32Z+zdgfXdXY8X9uGX5bN6EoPEIo=
|
||||
k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA=
|
||||
k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs=
|
||||
k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
|
||||
k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY=
|
||||
k8s.io/cli-runtime v0.21.1 h1:Oj/iZxa7LLXrhzShaLNF4rFJEIEBTDHj0dJw4ra2vX4=
|
||||
k8s.io/cli-runtime v0.21.1/go.mod h1:TI9Bvl8lQWZB2KqE91QLCp9AZE4l29zNFnj/x4IX4Fw=
|
||||
k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4=
|
||||
k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs=
|
||||
k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q=
|
||||
k8s.io/component-base v0.21.1 h1:iLpj2btXbR326s/xNQWmPNGu0gaYSjzn7IN/5i28nQw=
|
||||
k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA=
|
||||
k8s.io/component-helpers v0.21.1/go.mod h1:FtC1flbiQlosHQrLrRUulnKxE4ajgWCGy/67fT2GRlQ=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/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.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
|
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||
k8s.io/kubectl v0.21.1 h1:ySEusoeSgSDSiSBncDMsNrthSa3OSlXqT4R2rf1VFTw=
|
||||
k8s.io/kubectl v0.21.1/go.mod h1:PMYR88MqESuysBM/MX+Vu4JbX/50nY4d4kny+SPEI2U=
|
||||
k8s.io/metrics v0.21.1/go.mod h1:pyDVLsLe++FIGDBFU80NcW4xMFsuiVTWL8Zfi7+PpNo=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210517184530-5a248b5acedc h1:cIS13bDBZaWqngldgGuDypv4z+zjcYgTKv72k6bMAn0=
|
||||
k8s.io/utils v0.0.0-20210517184530-5a248b5acedc/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
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.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/cli-utils v0.26.0 h1:N1X1NVN19+daTihVimkSVNMgiVPIHG9OO3SJPh6SBQI=
|
||||
sigs.k8s.io/cli-utils v0.26.0/go.mod h1:myCFn83XMe7vC1ZX5CEJJIY2cqsl6IxYI727mLW1mfE=
|
||||
sigs.k8s.io/controller-runtime v0.9.0-beta.5.0.20210524185538-7181f1162e79 h1:unv8eVaIbf/1vh/ewJfHns6ffKF69fwUxZZpaxQOb7g=
|
||||
sigs.k8s.io/controller-runtime v0.9.0-beta.5.0.20210524185538-7181f1162e79/go.mod h1:rgf+cBz72pYlKXDRNhI1WFQv/S86EMUV4/ySmsEYgHk=
|
||||
sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY=
|
||||
sigs.k8s.io/kustomize/api v0.8.11 h1:LzQzlq6Z023b+mBtc6v72N2mSHYmN8x7ssgbf/hv0H8=
|
||||
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
|
||||
sigs.k8s.io/kustomize/cmd/config v0.9.10/go.mod h1:Mrby0WnRH7hA6OwOYnYpfpiY0WJIMgYrEDfwOeFdMK0=
|
||||
sigs.k8s.io/kustomize/kustomize/v4 v4.1.2/go.mod h1:PxBvo4WGYlCLeRPL+ziT64wBXqbgfcalOS/SXa/tcyo=
|
||||
sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg=
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0 h1:9KhiCPKaVyuPcgOLJXkvytOvjMJLoxpjodiycb4gHsA=
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
162
krm-functions/applier/image/main.go
Normal file
162
krm-functions/applier/image/main.go
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
v1 "k8s.io/client-go/applyconfigurations/core/v1"
|
||||
"k8s.io/klog/v2"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"sigs.k8s.io/cli-utils/cmd/printers"
|
||||
"sigs.k8s.io/cli-utils/pkg/apply"
|
||||
"sigs.k8s.io/cli-utils/pkg/common"
|
||||
"sigs.k8s.io/cli-utils/pkg/errors"
|
||||
"sigs.k8s.io/cli-utils/pkg/inventory"
|
||||
"sigs.k8s.io/cli-utils/pkg/util/factory"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/framework"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/framework/command"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
|
||||
"opendev.org/airship/airshipctl/krm-functions/applier/image/poller"
|
||||
"opendev.org/airship/airshipctl/krm-functions/applier/image/types"
|
||||
)
|
||||
|
||||
const (
|
||||
airshipNamespace = "airshipit"
|
||||
)
|
||||
|
||||
// Config is an extension of ApplyConfig struct with added streams
|
||||
type Config struct {
|
||||
*types.ApplyConfig
|
||||
Streams genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
func factoryFromKubeConfig(path, context string) cmdutil.Factory {
|
||||
kf := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
|
||||
kf.KubeConfig = &path
|
||||
kf.Context = &context
|
||||
return cmdutil.NewFactory(cmdutil.NewMatchVersionFlags(&factory.CachingRESTClientGetter{Delegate: kf}))
|
||||
}
|
||||
|
||||
func appendInventoryInfo(obj []*unstructured.Unstructured, name string) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
namespace := fmt.Sprintf("%s-%s", airshipNamespace, name)
|
||||
cmObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(v1.ConfigMap(fmt.Sprintf("inventory-%s",
|
||||
common.RandomStr()), namespace).WithLabels(map[string]string{common.InventoryLabel: name}))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
namespaceObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(v1.Namespace(namespace))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &unstructured.Unstructured{Object: cmObj}, append(obj, &unstructured.Unstructured{Object: namespaceObj}), nil
|
||||
}
|
||||
|
||||
// Run prepares config, applier and performs apply process
|
||||
func (c *Config) Run(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
if c.Debug {
|
||||
if err := flag.Set("v", "2"); err != nil {
|
||||
klog.V(2).Infof("unable to set debug flag: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
var objs []*unstructured.Unstructured
|
||||
for _, node := range nodes {
|
||||
m, err := node.Map()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
objs = append(objs, &unstructured.Unstructured{Object: m})
|
||||
}
|
||||
|
||||
f := factoryFromKubeConfig(c.Kubeconfig, c.Context)
|
||||
statusPoller, err := poller.NewStatusPoller(f, c.WaitOptions.Conditions...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
invFactory := inventory.ClusterInventoryClientFactory{}
|
||||
invClient, err := invFactory.NewInventoryClient(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
applier, err := apply.NewApplier(f, invClient, statusPoller)
|
||||
inv, obj, err := inventory.SplitUnstructureds(objs)
|
||||
if err != nil {
|
||||
klog.V(2).Infoln("injecting auto generated inventory object")
|
||||
inv, obj, err = appendInventoryInfo(obj, c.PhaseName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
opts := c.toCliOptions()
|
||||
err = printers.GetPrinter(printers.DefaultPrinter(), c.Streams).Print(
|
||||
applier.Run(context.Background(), inventory.WrapInventoryInfoObj(inv), obj, opts), opts.DryRunStrategy, true)
|
||||
klog.V(2).Infoln("applier channel closed")
|
||||
errors.CheckErr(c.Streams.ErrOut, err, "applier")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (c *Config) toCliOptions() apply.Options {
|
||||
dryRunStrategy := common.DryRunNone
|
||||
if c.DryRun {
|
||||
dryRunStrategy = common.DryRunClient
|
||||
}
|
||||
timeout := time.Second * time.Duration(c.WaitOptions.Timeout)
|
||||
pollInterval := time.Second * time.Duration(c.WaitOptions.PollInterval)
|
||||
|
||||
var emitStatusEvents bool
|
||||
// if wait timeout is 0, we don't want to status poller to emit any events,
|
||||
// this should disable waiting for resources
|
||||
if timeout != time.Duration(0) {
|
||||
emitStatusEvents = true
|
||||
}
|
||||
|
||||
return apply.Options{
|
||||
DryRunStrategy: dryRunStrategy,
|
||||
NoPrune: !c.PruneOptions.Prune,
|
||||
EmitStatusEvents: emitStatusEvents,
|
||||
ReconcileTimeout: timeout,
|
||||
PollInterval: pollInterval,
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
cfg := &Config{ApplyConfig: &types.ApplyConfig{}}
|
||||
cmd := command.Build(framework.SimpleProcessor{Filter: kio.FilterFunc(cfg.Run), Config: cfg.ApplyConfig},
|
||||
command.StandaloneDisabled, false)
|
||||
cfg.Streams = genericclioptions.IOStreams{In: cmd.InOrStdin(), Out: cmd.ErrOrStderr(), ErrOut: cmd.ErrOrStderr()}
|
||||
|
||||
klog.InitFlags(nil)
|
||||
klog.SetOutput(cmd.ErrOrStderr())
|
||||
defer klog.Flush()
|
||||
|
||||
if err := cmd.Execute(); err != nil {
|
||||
_, _ = fmt.Fprintln(cmd.ErrOrStderr())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
@ -20,10 +20,9 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/clusterreader"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
)
|
||||
|
||||
const allowedApplyErrors = 3
|
||||
@ -62,7 +61,7 @@ func (c *CachingClusterReader) Sync(ctx context.Context) error {
|
||||
if err != nil && strings.Contains(err.Error(), "request timed out") {
|
||||
c.applyErrors = append(c.applyErrors, err)
|
||||
if len(c.applyErrors) <= allowedApplyErrors {
|
||||
log.Printf("timeout error occurred during sync: '%v', skipping", err)
|
||||
klog.V(2).Infof("timeout error occurred during sync: '%v', skipping", err)
|
||||
return nil
|
||||
}
|
||||
}
|
@ -27,15 +27,16 @@ import (
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/engine"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/statusreaders"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/krm-functions/applier/image/types"
|
||||
)
|
||||
|
||||
// NewStatusPoller creates a new StatusPoller using the given clusterreader and mapper. The StatusPoller
|
||||
// will use the client for all calls to the cluster.
|
||||
func NewStatusPoller(f cmdutil.Factory, conditions ...v1alpha1.Condition) (*StatusPoller, error) {
|
||||
func NewStatusPoller(f cmdutil.Factory, conditions ...types.Condition) (*StatusPoller, error) {
|
||||
config, err := f.ToRESTConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -66,14 +67,14 @@ type StatusPoller struct {
|
||||
StatusReadersFactoryFunc engine.StatusReadersFactoryFunc
|
||||
|
||||
Engine *engine.PollerEngine
|
||||
conditions []v1alpha1.Condition
|
||||
conditions []types.Condition
|
||||
}
|
||||
|
||||
// Poll will create a new statusPollerRunner that will poll all the resources provided and report their status
|
||||
// back on the event channel returned. The statusPollerRunner can be canceled at any time by canceling the
|
||||
// context passed in.
|
||||
func (s *StatusPoller) Poll(
|
||||
ctx context.Context, identifiers []object.ObjMetadata, options polling.Options) <-chan event.Event {
|
||||
ctx context.Context, identifiers object.ObjMetadataSet, options polling.Options) <-chan event.Event {
|
||||
return s.Engine.Poll(ctx, identifiers, engine.Options{
|
||||
PollInterval: options.PollInterval,
|
||||
ClusterReaderFactoryFunc: map[bool]engine.ClusterReaderFactoryFunc{true: clusterReaderFactoryFunc(options.UseCache),
|
||||
@ -91,7 +92,7 @@ func (s *StatusPoller) Poll(
|
||||
func (s *StatusPoller) createStatusReadersFactory() engine.StatusReadersFactoryFunc {
|
||||
return func(reader engine.ClusterReader, mapper meta.RESTMapper) (
|
||||
map[schema.GroupKind]engine.StatusReader, engine.StatusReader) {
|
||||
defaultStatusReader := statusreaders.NewGenericStatusReader(reader, mapper)
|
||||
defaultStatusReader := statusreaders.NewGenericStatusReader(reader, mapper, status.Compute)
|
||||
replicaSetStatusReader := statusreaders.NewReplicaSetStatusReader(reader, mapper, defaultStatusReader)
|
||||
deploymentStatusReader := statusreaders.NewDeploymentResourceReader(reader, mapper, replicaSetStatusReader)
|
||||
statefulSetStatusReader := statusreaders.NewStatefulSetResourceReader(reader, mapper, defaultStatusReader)
|
||||
@ -104,8 +105,8 @@ func (s *StatusPoller) createStatusReadersFactory() engine.StatusReadersFactoryF
|
||||
|
||||
if len(s.conditions) > 0 {
|
||||
cr := NewCustomResourceReader(reader, mapper, s.conditions...)
|
||||
for _, tm := range s.conditions {
|
||||
statusReaders[tm.GroupVersionKind().GroupKind()] = cr
|
||||
for _, cm := range s.conditions {
|
||||
statusReaders[cm.GroupVersionKind().GroupKind()] = cr
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +120,7 @@ func (s *StatusPoller) createStatusReadersFactory() engine.StatusReadersFactoryF
|
||||
// decided here rather than based on information passed in to the factory function. Thus, the decision
|
||||
// for which implementation is decided when the StatusPoller is created.
|
||||
func clusterReaderFactoryFunc(useCache bool) engine.ClusterReaderFactoryFunc {
|
||||
return func(r client.Reader, mapper meta.RESTMapper, identifiers []object.ObjMetadata) (engine.ClusterReader, error) {
|
||||
return func(r client.Reader, mapper meta.RESTMapper, identifiers object.ObjMetadataSet) (engine.ClusterReader, error) {
|
||||
if useCache {
|
||||
cr, err := clusterreader.NewCachingClusterReader(r, mapper, identifiers)
|
||||
if err != nil {
|
@ -16,18 +16,19 @@ package poller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
apitypes "k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/engine"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/krm-functions/applier/image/types"
|
||||
)
|
||||
|
||||
// CustomResourceReader is a wrapper for clu-utils genericClusterReader struct
|
||||
@ -49,7 +50,7 @@ var _ engine.StatusReader = &CustomResourceReader{}
|
||||
|
||||
// NewCustomResourceReader implements custom logic to retrieve resource's status
|
||||
func NewCustomResourceReader(reader engine.ClusterReader, mapper meta.RESTMapper,
|
||||
conditions ...v1alpha1.Condition) engine.StatusReader {
|
||||
conditions ...types.Condition) engine.StatusReader {
|
||||
condMap := make(map[schema.GroupKind]Expression)
|
||||
for _, cond := range conditions {
|
||||
condMap[cond.GroupVersionKind().GroupKind()] = Expression{
|
||||
@ -98,6 +99,7 @@ func (c *CustomResourceReader) ReadStatusForObject(_ context.Context,
|
||||
Identifier: toIdentifier(obj),
|
||||
Status: status.UnknownStatus,
|
||||
Error: err,
|
||||
Message: fmt.Sprintf("Unable to parse jsonpath '%s' in resource: %v", val.Condition, err),
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +114,7 @@ func (c *CustomResourceReader) ReadStatusForObject(_ context.Context,
|
||||
return &event.ResourceStatus{
|
||||
Identifier: toIdentifier(obj),
|
||||
Status: status.InProgressStatus,
|
||||
Message: fmt.Sprintf("Resource has not reached state '%s' at jsonpath '%s' yet", val.Value, val.Condition),
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +139,7 @@ func (c *CustomResourceReader) lookupResource(ctx context.Context,
|
||||
|
||||
var u unstructured.Unstructured
|
||||
u.SetGroupVersionKind(groupVersionKind)
|
||||
key := types.NamespacedName{
|
||||
key := apitypes.NamespacedName{
|
||||
Name: identifier.Name,
|
||||
Namespace: identifier.Namespace,
|
||||
}
|
52
krm-functions/applier/image/types/types.go
Executable file
52
krm-functions/applier/image/types/types.go
Executable file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ApplyConfig provides instructions on how to apply resources to kubernetes cluster
|
||||
type ApplyConfig struct {
|
||||
WaitOptions ApplyWaitOptions `json:"waitOptions,omitempty"`
|
||||
PruneOptions ApplyPruneOptions `json:"pruneOptions,omitempty"`
|
||||
Kubeconfig string `json:"kubeconfig,omitempty"`
|
||||
Context string `json:"context,omitempty"`
|
||||
DryRun bool `json:"druRun,omitempty"`
|
||||
Debug bool `json:"debug,omitempty"`
|
||||
PhaseName string `json:"phaseName,omitempty"`
|
||||
}
|
||||
|
||||
// ApplyWaitOptions provides instructions how to wait for kubernetes resources
|
||||
type ApplyWaitOptions struct {
|
||||
// Timeout in seconds
|
||||
Timeout int `json:"timeout,omitempty"`
|
||||
// PollInterval in seconds
|
||||
PollInterval int `json:"pollInterval,omitempty"`
|
||||
Conditions []Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// ApplyPruneOptions provides instructions how to prune for kubernetes resources
|
||||
type ApplyPruneOptions struct {
|
||||
Prune bool `json:"prune,omitempty"`
|
||||
}
|
||||
|
||||
// Condition is a jsonpath for particular TypeMeta which indicates what state to wait
|
||||
type Condition struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
JSONPath string `json:"jsonPath,omitempty"`
|
||||
// Value is desired state to wait for, if no value specified - just existence of provided jsonPath will be checked
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
24
krm-functions/applier/local-resource/example-use.yaml
Executable file
24
krm-functions/applier/local-resource/example-use.yaml
Executable file
@ -0,0 +1,24 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: KubernetesApply
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/deploy-k8s: "false"
|
||||
name: kubernetes-apply-controlplane
|
||||
config:
|
||||
waitOptions:
|
||||
timeout: 5000
|
||||
pollInterval: 30
|
||||
pruneOptions:
|
||||
prune: false
|
@ -23,6 +23,7 @@ apiVersion: cluster.x-k8s.io/v1alpha3
|
||||
kind: MachineDeployment
|
||||
metadata:
|
||||
name: "target-cluster-md-0"
|
||||
namespace: default
|
||||
spec:
|
||||
clusterName: "target-cluster"
|
||||
replicas: ${ WORKER_MACHINE_COUNT }
|
||||
|
@ -1,7 +1,6 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- kubeadmconfigtemplate.yaml
|
||||
- metal3machinetemplate.yaml
|
||||
- machinedeployment.yaml
|
||||
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: target-infra
|
@ -7,7 +7,8 @@ metadata:
|
||||
name: kubernetes-apply
|
||||
config:
|
||||
waitOptions:
|
||||
timeout: 2600
|
||||
timeout: 2500
|
||||
pollInterval: 10
|
||||
conditions:
|
||||
- apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
@ -24,8 +25,8 @@ metadata:
|
||||
name: kubernetes-apply-controlplane
|
||||
config:
|
||||
waitOptions:
|
||||
timeout: 5000
|
||||
pollInterval: 30
|
||||
timeout: 3500
|
||||
pollInterval: 20
|
||||
conditions:
|
||||
- apiVersion: metal3.io/v1alpha1
|
||||
kind: BareMetalHost
|
||||
@ -579,6 +580,17 @@ spec:
|
||||
---
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: GenericContainer
|
||||
metadata:
|
||||
name: applier
|
||||
labels:
|
||||
airshipit.org/deploy-k8s: "false"
|
||||
spec:
|
||||
type: krm
|
||||
image: localhost/applier:latest
|
||||
hostNetwork: true
|
||||
---
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: GenericContainer
|
||||
metadata:
|
||||
name: merge-kubeconfig
|
||||
labels:
|
||||
|
@ -97,18 +97,11 @@ phases:
|
||||
- name: kubectl-wait-cluster-target
|
||||
# Power off Ephemeral baremetal host avoid DHCP conflict
|
||||
- name: power-off-ephemeral
|
||||
# Create target k8s cluster resources
|
||||
- name: controlplane-target
|
||||
# List all nodes in target cluster
|
||||
# Scripts for this phase placed in manifests/function/phase-helpers/get_node/
|
||||
# To get ConfigMap for this phase, execute `airshipctl phase render --source config -k ConfigMap`
|
||||
# and find ConfigMap with name kubectl-get-node
|
||||
- name: kubectl-get-node-target
|
||||
# List all pods in target cluster
|
||||
# Scripts for this phase placed in manifests/function/phase-helpers/get_pods/
|
||||
# To get ConfigMap for this phase, execute `airshipctl phase render --source config -k ConfigMap`
|
||||
# and find ConfigMap with name kubectl-get-pods
|
||||
- name: kubectl-get-pods-target
|
||||
# Deploy worker node
|
||||
- name: workers-target
|
||||
# Waiting for node to be provisioned
|
||||
|
@ -32,6 +32,11 @@ type KubernetesApply struct {
|
||||
type ApplyConfig struct {
|
||||
WaitOptions ApplyWaitOptions `json:"waitOptions,omitempty"`
|
||||
PruneOptions ApplyPruneOptions `json:"pruneOptions,omitempty"`
|
||||
Kubeconfig string `json:"kubeconfig,omitempty"`
|
||||
Context string `json:"context,omitempty"`
|
||||
DryRun bool `json:"druRun,omitempty"`
|
||||
Debug bool `json:"debug,omitempty"`
|
||||
PhaseName string `json:"phaseName,omitempty"`
|
||||
}
|
||||
|
||||
// ApplyWaitOptions provides instructions how to wait for kubernetes resources
|
||||
|
@ -57,6 +57,15 @@ const (
|
||||
ClusterctlContainerKind = "GenericContainer"
|
||||
// ClusterctlContainerName defines Name for clustertctl container
|
||||
ClusterctlContainerName = "clusterctl"
|
||||
|
||||
// ApplierContainerGroup defines Group for applier container
|
||||
ApplierContainerGroup = "airshipit.org"
|
||||
// ApplierContainerVersion defines Version for applier container
|
||||
ApplierContainerVersion = "v1alpha1"
|
||||
// ApplierContainerKind defines Kind for applier container
|
||||
ApplierContainerKind = "GenericContainer"
|
||||
// ApplierContainerName defines Name for applier container
|
||||
ApplierContainerName = "applier"
|
||||
)
|
||||
|
||||
// KustomizationFile is used for kustomization file
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||
)
|
||||
@ -210,3 +209,11 @@ func NewClusterctlContainerExecutorSelector() Selector {
|
||||
ClusterctlContainerKind).
|
||||
ByName(ClusterctlContainerName)
|
||||
}
|
||||
|
||||
// NewApplierContainerExecutorSelector returns selector to get executor documents for applier container
|
||||
func NewApplierContainerExecutorSelector() Selector {
|
||||
return NewSelector().ByGvk(ApplierContainerGroup,
|
||||
ApplierContainerVersion,
|
||||
ApplierContainerKind).
|
||||
ByName(ApplierContainerName)
|
||||
}
|
||||
|
@ -17,9 +17,6 @@ package events
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
applyevent "sigs.k8s.io/cli-utils/pkg/apply/event"
|
||||
statuspollerevent "sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||
)
|
||||
|
||||
// Type indicates type of the event
|
||||
@ -48,15 +45,20 @@ const (
|
||||
type Event struct {
|
||||
Type Type
|
||||
Timestamp time.Time
|
||||
ApplierEvent applyevent.Event
|
||||
ApplierEvent ApplierEvent
|
||||
ErrorEvent ErrorEvent
|
||||
StatusPollerEvent statuspollerevent.Event
|
||||
ClusterctlEvent ClusterctlEvent
|
||||
BootstrapEvent BootstrapEvent
|
||||
GenericContainerEvent GenericContainerEvent
|
||||
BaremetalManagerEvent BaremetalManagerEvent
|
||||
}
|
||||
|
||||
// ApplierEvent is produced by k8s_apply executor
|
||||
type ApplierEvent struct {
|
||||
Operation string
|
||||
Message string
|
||||
}
|
||||
|
||||
//GenericEvent generalized type for custom events
|
||||
type GenericEvent struct {
|
||||
Type string
|
||||
|
@ -15,11 +15,6 @@
|
||||
package events
|
||||
|
||||
import (
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"sigs.k8s.io/cli-utils/cmd/printers"
|
||||
applyevent "sigs.k8s.io/cli-utils/pkg/apply/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/common"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
)
|
||||
|
||||
@ -32,19 +27,15 @@ type EventProcessor interface {
|
||||
// DefaultProcessor is implementation of EventProcessor
|
||||
type DefaultProcessor struct {
|
||||
errors []error
|
||||
applierChan chan<- applyevent.Event
|
||||
genericPrinter GenericPrinter
|
||||
}
|
||||
|
||||
// NewDefaultProcessor returns instance of DefaultProcessor as interface Implementation
|
||||
func NewDefaultProcessor(streams genericclioptions.IOStreams) EventProcessor {
|
||||
applyCh := make(chan applyevent.Event)
|
||||
go printers.GetPrinter(printers.EventsPrinter, streams).Print(applyCh, common.DryRunNone)
|
||||
func NewDefaultProcessor() EventProcessor {
|
||||
// printer for custom airshipctl events
|
||||
genericPrinter := NewGenericPrinter(log.Writer(), JSONPrinter)
|
||||
return &DefaultProcessor{
|
||||
errors: []error{},
|
||||
applierChan: applyCh,
|
||||
genericPrinter: genericPrinter,
|
||||
}
|
||||
}
|
||||
@ -53,8 +44,6 @@ func NewDefaultProcessor(streams genericclioptions.IOStreams) EventProcessor {
|
||||
func (p *DefaultProcessor) Process(ch <-chan Event) error {
|
||||
for e := range ch {
|
||||
switch e.Type {
|
||||
case ApplierType:
|
||||
p.processApplierEvent(e.ApplierEvent)
|
||||
case ErrorType:
|
||||
log.Printf("Received error on event channel %v", e.ErrorEvent)
|
||||
p.errors = append(p.errors, e.ErrorEvent.Error)
|
||||
@ -75,17 +64,6 @@ func (p *DefaultProcessor) Process(ch <-chan Event) error {
|
||||
|
||||
// Close cleans up the auxiliary channels used to process events
|
||||
func (p *DefaultProcessor) Close() {
|
||||
close(p.applierChan)
|
||||
}
|
||||
|
||||
func (p *DefaultProcessor) processApplierEvent(e applyevent.Event) {
|
||||
if e.Type == applyevent.ErrorType {
|
||||
log.Printf("Received error when applying resources to kubernetes: %v", e.ErrorEvent.Err)
|
||||
p.errors = append(p.errors, e.ErrorEvent.Err)
|
||||
// Don't write errors events to applier channel, as it will use os.Exit to stop program execution
|
||||
return
|
||||
}
|
||||
p.applierChan <- e
|
||||
}
|
||||
|
||||
// Check list of errors, and verify that these errors we are able to tolerate
|
||||
|
@ -22,12 +22,11 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/utils"
|
||||
k8stest "opendev.org/airship/airshipctl/testutil/k8sutils"
|
||||
)
|
||||
|
||||
func TestDefaultProcessor(t *testing.T) {
|
||||
proc := events.NewDefaultProcessor(utils.Streams())
|
||||
proc := events.NewDefaultProcessor()
|
||||
defer proc.Close()
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -46,7 +45,7 @@ func TestDefaultProcessor(t *testing.T) {
|
||||
{
|
||||
name: "error event",
|
||||
events: errApplyEvents(),
|
||||
errString: "apply-error",
|
||||
errString: "somerror",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1,269 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package applier
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierror "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
cliapply "sigs.k8s.io/cli-utils/pkg/apply"
|
||||
applyevent "sigs.k8s.io/cli-utils/pkg/apply/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/apply/poller"
|
||||
clicommon "sigs.k8s.io/cli-utils/pkg/common"
|
||||
"sigs.k8s.io/cli-utils/pkg/inventory"
|
||||
"sigs.k8s.io/cli-utils/pkg/manifestreader"
|
||||
"sigs.k8s.io/cli-utils/pkg/provider"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
airpoller "opendev.org/airship/airshipctl/pkg/k8s/poller"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/utils"
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultNamespace to store inventory objects in
|
||||
DefaultNamespace = "airshipit"
|
||||
)
|
||||
|
||||
// Applier delivers documents to kubernetes in a declarative way
|
||||
type Applier struct {
|
||||
Driver Driver
|
||||
Factory cmdutil.Factory
|
||||
Poller poller.Poller
|
||||
ManifestReaderFactory utils.ManifestReaderFactory
|
||||
eventChannel chan events.Event
|
||||
conditions []v1alpha1.Condition
|
||||
}
|
||||
|
||||
// ReaderFactory function that returns reader factory interface
|
||||
type ReaderFactory func(validate bool, bundle document.Bundle, factory cmdutil.Factory) manifestreader.ManifestReader
|
||||
|
||||
// NewApplier returns instance of Applier
|
||||
func NewApplier(eventCh chan events.Event, f cmdutil.Factory, conditions []v1alpha1.Condition) *Applier {
|
||||
cf := provider.NewProvider(f)
|
||||
return &Applier{
|
||||
Factory: f,
|
||||
ManifestReaderFactory: utils.DefaultManifestReaderFactory,
|
||||
Driver: &Adaptor{
|
||||
CliUtilsApplier: cliapply.NewApplier(cf),
|
||||
},
|
||||
eventChannel: eventCh,
|
||||
conditions: conditions,
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyBundle apply bundle to kubernetes cluster
|
||||
func (a *Applier) ApplyBundle(bundle document.Bundle, ao ApplyOptions) {
|
||||
log.Debugf("Getting infos for bundle, inventory id is %s", ao.BundleName)
|
||||
objects, err := a.getObjects(ao.BundleName, bundle, ao.DryRunStrategy)
|
||||
if err != nil {
|
||||
handleError(a.eventChannel, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
ch := a.Driver.Run(ctx, objects, cliApplyOptions(ao))
|
||||
for e := range ch {
|
||||
a.eventChannel <- events.Event{
|
||||
Type: events.ApplierType,
|
||||
ApplierEvent: e,
|
||||
}
|
||||
}
|
||||
log.Debugf("applier channel closed")
|
||||
}
|
||||
|
||||
func (a *Applier) getObjects(
|
||||
bundleName string,
|
||||
bundle document.Bundle,
|
||||
dryRun clicommon.DryRunStrategy) ([]*unstructured.Unstructured, error) {
|
||||
if bundle == nil {
|
||||
return nil, ErrNilBundle{}
|
||||
}
|
||||
selector := document.
|
||||
NewSelector().
|
||||
ByLabel(clicommon.InventoryLabel).
|
||||
ByKind(document.ConfigMapKind)
|
||||
// if we could find exactly one inventory document, we don't do anything else with it
|
||||
_, err := bundle.SelectOne(selector)
|
||||
// if we got an error, which means we could not find Config Map with inventory ID at rest
|
||||
// now we need to generate and inject one at runtime
|
||||
if err != nil && errors.As(err, &document.ErrDocNotFound{}) {
|
||||
log.Debug("Inventory Object config Map not found, auto generating Inventory object")
|
||||
invDoc, innerErr := NewInventoryDocument(bundleName)
|
||||
if innerErr != nil {
|
||||
// this should never happen
|
||||
log.Debug("Failed to create new inventory document")
|
||||
return nil, innerErr
|
||||
}
|
||||
log.Debugf("Injecting Inventory Object: %v into bundle", invDoc)
|
||||
innerErr = bundle.Append(invDoc)
|
||||
if innerErr != nil {
|
||||
log.Debug("Couldn't append bundle with inventory document")
|
||||
return nil, innerErr
|
||||
}
|
||||
log.Debugf("Making sure that inventory object namespace %s exists", invDoc.GetNamespace())
|
||||
innerErr = a.ensureNamespaceExists(invDoc.GetNamespace(), dryRun)
|
||||
if innerErr != nil {
|
||||
return nil, innerErr
|
||||
}
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mapper, err := a.Factory.ToRESTMapper()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if a.Poller == nil {
|
||||
a.Poller, err = airpoller.NewStatusPoller(a.Factory, a.conditions...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err = a.Driver.Initialize(a.Poller); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a.ManifestReaderFactory(false, bundle, mapper).Read()
|
||||
}
|
||||
|
||||
func (a *Applier) ensureNamespaceExists(name string, dryRun clicommon.DryRunStrategy) error {
|
||||
if dryRun != clicommon.DryRunNone {
|
||||
log.Printf("Dryrun strategy is specified, otherwise Namespace '%s' would have been created", name)
|
||||
return nil
|
||||
}
|
||||
clientSet, err := a.Factory.KubernetesClientSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nsClient := clientSet.CoreV1().Namespaces()
|
||||
_, err = nsClient.Create(
|
||||
context.Background(),
|
||||
&v1.Namespace{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Namespace",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
},
|
||||
metav1.CreateOptions{})
|
||||
if err != nil && !apierror.IsAlreadyExists(err) {
|
||||
// we got error and error doesn't say that NS already exist
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cliApplyOptions(ao ApplyOptions) cliapply.Options {
|
||||
var emitStatusEvents bool
|
||||
// if wait timeout is 0, we don't want to status poller to emit any events,
|
||||
// this should disable waiting for resources
|
||||
if ao.WaitTimeout != time.Duration(0) {
|
||||
emitStatusEvents = true
|
||||
}
|
||||
return cliapply.Options{
|
||||
EmitStatusEvents: emitStatusEvents,
|
||||
ReconcileTimeout: ao.WaitTimeout,
|
||||
NoPrune: !ao.Prune,
|
||||
DryRunStrategy: ao.DryRunStrategy,
|
||||
PollInterval: ao.PollInterval,
|
||||
}
|
||||
}
|
||||
|
||||
// Driver to cli-utils apply
|
||||
type Driver interface {
|
||||
Initialize(p poller.Poller) error
|
||||
Run(ctx context.Context, infos []*unstructured.Unstructured, options cliapply.Options) <-chan applyevent.Event
|
||||
}
|
||||
|
||||
// Adaptor is implementation of driver interface
|
||||
type Adaptor struct {
|
||||
CliUtilsApplier *cliapply.Applier
|
||||
Factory cmdutil.Factory
|
||||
}
|
||||
|
||||
// Initialize sets fake required command line flags for underlying cli-utils package
|
||||
func (a *Adaptor) Initialize(p poller.Poller) error {
|
||||
err := a.CliUtilsApplier.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// status poller needs to be set only after the Initialize method is executed
|
||||
if p != nil {
|
||||
a.CliUtilsApplier.StatusPoller = p
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run perform apply operation
|
||||
func (a *Adaptor) Run(ctx context.Context, objects []*unstructured.Unstructured,
|
||||
options cliapply.Options) <-chan applyevent.Event {
|
||||
inv, objects, err := inventory.SplitUnstructureds(objects)
|
||||
if err != nil {
|
||||
log.Debugf("Error while splitting objects %v", err)
|
||||
return nil
|
||||
}
|
||||
return a.CliUtilsApplier.Run(ctx, inv, objects, options)
|
||||
}
|
||||
|
||||
// NewInventoryDocument returns default config map with inventory Id to group up the objects
|
||||
func NewInventoryDocument(inventoryID string) (document.Document, error) {
|
||||
cm := v1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: document.ConfigMapKind,
|
||||
APIVersion: document.ConfigMapVersion,
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
// name here is a dummy name, cli utils won't use this name, this config map simply parsed
|
||||
// for inventory ID from label, and then ignores this config map
|
||||
Name: fmt.Sprintf("%s-%s", "airshipit", inventoryID),
|
||||
// TODO this limits us to single namespace. research passing this as parameter from
|
||||
// somewhere higher level package that uses this module
|
||||
Namespace: DefaultNamespace,
|
||||
Labels: map[string]string{
|
||||
clicommon.InventoryLabel: inventoryID,
|
||||
},
|
||||
},
|
||||
Data: map[string]string{},
|
||||
}
|
||||
b, err := yaml.Marshal(cm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return document.NewDocumentFromBytes(b)
|
||||
}
|
||||
|
||||
func handleError(ch chan<- events.Event, err error) {
|
||||
ch <- events.Event{
|
||||
Type: events.ErrorType,
|
||||
ErrorEvent: events.ErrorEvent{
|
||||
Error: err,
|
||||
},
|
||||
}
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package applier_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/cli-utils/pkg/apply/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/apply/poller"
|
||||
"sigs.k8s.io/cli-utils/pkg/common"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/applier"
|
||||
"opendev.org/airship/airshipctl/testutil"
|
||||
k8stest "opendev.org/airship/airshipctl/testutil/k8sutils"
|
||||
)
|
||||
|
||||
func TestFakeApplier(t *testing.T) {
|
||||
ch := make(chan events.Event)
|
||||
a := applier.NewFakeApplier(ch,
|
||||
k8stest.SuccessEvents(), k8stest.FakeFactory(t, []k8stest.ClientHandler{}))
|
||||
assert.NotNil(t, a)
|
||||
}
|
||||
|
||||
// TODO Develop more coverage with tests
|
||||
func TestApplierRun(t *testing.T) {
|
||||
bundle := testutil.NewTestBundle(t, "testdata/source_bundle")
|
||||
replicationController, err := bundle.SelectOne(document.NewSelector().ByKind("ReplicationController"))
|
||||
require.NoError(t, err)
|
||||
b, err := replicationController.AsYAML()
|
||||
require.NoError(t, err)
|
||||
f := k8stest.FakeFactory(t,
|
||||
[]k8stest.ClientHandler{
|
||||
&k8stest.InventoryObjectHandler{},
|
||||
&k8stest.NamespaceHandler{},
|
||||
&k8stest.GenericHandler{
|
||||
Obj: &corev1.ReplicationController{},
|
||||
Bytes: b,
|
||||
URLPath: "/namespaces/%s/replicationcontrollers",
|
||||
Namespace: replicationController.GetNamespace(),
|
||||
},
|
||||
})
|
||||
defer f.Cleanup()
|
||||
tests := []struct {
|
||||
name string
|
||||
driver applier.Driver
|
||||
expectErr bool
|
||||
expectedString string
|
||||
bundle document.Bundle
|
||||
poller poller.Poller
|
||||
}{
|
||||
{
|
||||
name: "init-err",
|
||||
driver: applier.NewFakeAdaptor().WithInitError(fmt.Errorf("init-err")),
|
||||
expectedString: "init-err",
|
||||
bundle: bundle,
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "can't reach cluster",
|
||||
expectedString: "connection refused",
|
||||
expectErr: true,
|
||||
bundle: bundle,
|
||||
poller: &applier.FakePoller{},
|
||||
},
|
||||
{
|
||||
name: "bundle failure",
|
||||
expectedString: "nil bundle provided",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "success",
|
||||
expectErr: false,
|
||||
bundle: bundle,
|
||||
driver: applier.NewFakeAdaptor().WithEvents(k8stest.SuccessEvents()),
|
||||
},
|
||||
{
|
||||
name: "set poller",
|
||||
expectErr: false,
|
||||
bundle: bundle,
|
||||
driver: applier.NewFakeAdaptor().WithEvents(k8stest.SuccessEvents()),
|
||||
poller: &applier.FakePoller{},
|
||||
},
|
||||
{
|
||||
name: "two configmaps present",
|
||||
expectErr: true,
|
||||
bundle: newBundle("testdata/two_cm_bundle", t),
|
||||
driver: applier.NewFakeAdaptor().WithEvents(k8stest.SuccessEvents()),
|
||||
expectedString: "found more than one document",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// create default applier
|
||||
eventChan := make(chan events.Event)
|
||||
a := applier.NewApplier(eventChan, f, nil)
|
||||
opts := applier.ApplyOptions{
|
||||
WaitTimeout: time.Second * 5,
|
||||
BundleName: "test-bundle",
|
||||
DryRunStrategy: common.DryRunClient,
|
||||
}
|
||||
if tt.driver != nil {
|
||||
a.Driver = tt.driver
|
||||
}
|
||||
if tt.poller != nil {
|
||||
a.Poller = tt.poller
|
||||
}
|
||||
// start writing to channel
|
||||
go func(bundle document.Bundle, applyOpts applier.ApplyOptions) {
|
||||
// since applier doesn't close channel anymore, we need to close it
|
||||
// after it applier is finished
|
||||
defer close(eventChan)
|
||||
a.ApplyBundle(bundle, applyOpts)
|
||||
}(tt.bundle, opts)
|
||||
|
||||
var airEvents []events.Event
|
||||
for e := range eventChan {
|
||||
airEvents = append(airEvents, e)
|
||||
}
|
||||
|
||||
var errs []error
|
||||
for _, e := range airEvents {
|
||||
if e.Type == events.ErrorType {
|
||||
errs = append(errs, e.ErrorEvent.Error)
|
||||
} else if e.Type == events.ApplierType && e.ApplierEvent.Type == event.ErrorType {
|
||||
errs = append(errs, e.ApplierEvent.ErrorEvent.Err)
|
||||
}
|
||||
}
|
||||
if tt.expectErr {
|
||||
t.Logf("errors are %v \n", errs)
|
||||
require.Len(t, errs, 1)
|
||||
require.NotNil(t, errs[0])
|
||||
// check if error contains string
|
||||
assert.Contains(t, errs[0].Error(), tt.expectedString)
|
||||
} else {
|
||||
assert.Len(t, errs, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newBundle(path string, t *testing.T) document.Bundle {
|
||||
t.Helper()
|
||||
b, err := document.NewBundleByPath(path)
|
||||
require.NoError(t, err)
|
||||
return b
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package applier
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/cli-utils/pkg/common"
|
||||
|
||||
"time"
|
||||
)
|
||||
|
||||
// ApplyOptions struct that hold options for apply operation
|
||||
type ApplyOptions struct {
|
||||
WaitTimeout time.Duration
|
||||
PollInterval time.Duration
|
||||
DryRunStrategy common.DryRunStrategy
|
||||
Prune bool
|
||||
BundleName string
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package applier
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ErrApply returned for not implemented features
|
||||
type ErrApply struct {
|
||||
errors []error
|
||||
}
|
||||
|
||||
func (e ErrApply) Error() string {
|
||||
// TODO make printing more readable here
|
||||
return fmt.Sprintf("Applying of resources to kubernetes cluster has failed, errors are:\n%v", e.errors)
|
||||
}
|
||||
|
||||
// ErrNilBundle returned when bundle is nil
|
||||
type ErrNilBundle struct {
|
||||
}
|
||||
|
||||
func (e ErrNilBundle) Error() string {
|
||||
return "nil bundle provided"
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package applier
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
cliapply "sigs.k8s.io/cli-utils/pkg/apply"
|
||||
applyevent "sigs.k8s.io/cli-utils/pkg/apply/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/apply/poller"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
|
||||
pollevent "sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/utils"
|
||||
)
|
||||
|
||||
// FakeAdaptor is implementation of driver interface
|
||||
type FakeAdaptor struct {
|
||||
initErr error
|
||||
events []applyevent.Event
|
||||
}
|
||||
|
||||
var _ Driver = FakeAdaptor{}
|
||||
|
||||
// NewFakeAdaptor returns a fake driver interface with convenience methods for testing
|
||||
func NewFakeAdaptor() FakeAdaptor {
|
||||
return FakeAdaptor{}
|
||||
}
|
||||
|
||||
// Initialize implements driver
|
||||
func (fa FakeAdaptor) Initialize(p poller.Poller) error {
|
||||
return fa.initErr
|
||||
}
|
||||
|
||||
// Run implements driver
|
||||
func (fa FakeAdaptor) Run(
|
||||
ctx context.Context,
|
||||
objects []*unstructured.Unstructured,
|
||||
options cliapply.Options) <-chan applyevent.Event {
|
||||
ch := make(chan applyevent.Event, len(fa.events))
|
||||
defer close(ch)
|
||||
for _, e := range fa.events {
|
||||
ch <- e
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// WithEvents set events for the adaptor
|
||||
func (fa FakeAdaptor) WithEvents(events []applyevent.Event) FakeAdaptor {
|
||||
fa.events = events
|
||||
return fa
|
||||
}
|
||||
|
||||
// WithInitError adds error to Initialize method
|
||||
func (fa FakeAdaptor) WithInitError(err error) FakeAdaptor {
|
||||
fa.initErr = err
|
||||
return fa
|
||||
}
|
||||
|
||||
// NewFakeApplier returns applier with events you want
|
||||
func NewFakeApplier(
|
||||
eventCh chan events.Event,
|
||||
events []applyevent.Event, f cmdutil.Factory) *Applier {
|
||||
return &Applier{
|
||||
Driver: NewFakeAdaptor().WithEvents(events),
|
||||
Poller: &FakePoller{},
|
||||
Factory: f,
|
||||
ManifestReaderFactory: utils.DefaultManifestReaderFactory,
|
||||
eventChannel: eventCh,
|
||||
}
|
||||
}
|
||||
|
||||
// FakePoller returns a poller that sends 2 complete events for now
|
||||
// TODO, make these events configurable.
|
||||
type FakePoller struct {
|
||||
}
|
||||
|
||||
// Poll implements poller interface
|
||||
func (fp *FakePoller) Poll(ctx context.Context, ids []object.ObjMetadata, opts polling.Options) <-chan pollevent.Event {
|
||||
events := []pollevent.Event{
|
||||
{
|
||||
EventType: pollevent.ResourceUpdateEvent,
|
||||
Resource: &pollevent.ResourceStatus{
|
||||
Identifier: object.ObjMetadata{
|
||||
Name: "test-rc",
|
||||
Namespace: "test",
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "v1",
|
||||
Kind: "ReplicationController",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
EventType: pollevent.ResourceUpdateEvent,
|
||||
Resource: &pollevent.ResourceStatus{
|
||||
Identifier: object.ObjMetadata{
|
||||
Name: "airshipit-test-bundle-4bf1e4a",
|
||||
Namespace: "airshipit",
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
ch := make(chan pollevent.Event, len(events))
|
||||
defer close(ch)
|
||||
for _, e := range events {
|
||||
ch <- e
|
||||
}
|
||||
return ch
|
||||
}
|
19
pkg/k8s/applier/testdata/kubeconfig.yaml
vendored
19
pkg/k8s/applier/testdata/kubeconfig.yaml
vendored
@ -1,19 +0,0 @@
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNU1Ea3lPVEUzTURNd09Wb1hEVEk1TURreU5qRTNNRE13T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUZyCkdxM0kyb2dZci81Y01Udy9Na1pORTNWQURzdEdyU240WjU2TDhPUGhMcUhDN2t1dno2dVpES3dCSGtGeTBNK2MKRXIzd2piUGE1aTV5NmkyMGtxSHBVMjdPZTA0dzBXV2s4N0RSZVlWaGNoZVJHRXoraWt3SndIcGRmMjJVemZNKwpkSDBzaUhuMVd6UnovYk4za3hMUzJlMnZ2U1Y3bmNubk1YRUd4OXV0MUY0NThHeWxxdmxXTUlWMzg5Q2didXFDCkcwcFdiMTBLM0RVZWdiT25Xa1FmSm5sTWRRVVZDUVdZZEZaaklrcWtkWi9hVTRobkNEV01oZXNWRnFNaDN3VVAKczhQay9BNWh1ZFFPbnFRNDVIWXZLdjZ5RjJWcDUyWExBRUx3NDJ4aVRKZlh0V1h4eHR6cU4wY1lyL2VxeS9XMQp1YVVGSW5xQjFVM0JFL1oxbmFrQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKUUVKQVBLSkFjVDVuK3dsWGJsdU9mS0J3c2gKZTI4R1c5R2QwM0N0NGF3RzhzMXE1ZHNua2tpZmVTUENHVFZ1SXF6UTZDNmJaSk9SMDMvVEl5ejh6NDJnaitDVApjWUZXZkltM2RKTnpRL08xWkdySXZZNWdtcWJtWDlpV0JaU24rRytEOGxubzd2aGMvY0tBRFR5OTMvVU92MThuCkdhMnIrRGJJcHcyTWVBVEl2elpxRS9RWlVSQ25DMmdjUFhTVzFqN2h4R3o1a3ZNcGVDZTdQYVUvdVFvblVHSWsKZ2t6ZzI4NHQvREhUUzc4N1V1SUg5cXBaV09yTFNMOGFBeUxQUHhWSXBteGZmbWRETE9TS2VUemRlTmxoSitUMwowQlBVaHBQTlJBNTNJN0hRQjhVUDR2elNONTkzZ1VFbVlFQ2Jic2RYSzB6ZVR6SDdWWHR2Zmd5WTVWWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
server: https://10.0.1.7:6443
|
||||
name: kubernetes_target
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kubernetes_target
|
||||
user: kubernetes-admin
|
||||
name: kubernetes-admin@kubernetes
|
||||
current-context: ""
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kubernetes-admin
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
|
2
pkg/k8s/applier/testdata/metadata.yaml
vendored
2
pkg/k8s/applier/testdata/metadata.yaml
vendored
@ -1,2 +0,0 @@
|
||||
phase:
|
||||
path: "source_bundle"
|
@ -1,2 +0,0 @@
|
||||
resources:
|
||||
- replicationcontroller.yaml
|
@ -1,22 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: test-rc
|
||||
namespace: test
|
||||
annotations:
|
||||
airshipit.org/initinfra: "workflow"
|
||||
labels:
|
||||
name: test-rc
|
||||
airshipit.org/initinfra: "workflow"
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: test-rc
|
||||
spec:
|
||||
containers:
|
||||
- name: test-rc
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
@ -1,2 +0,0 @@
|
||||
resources:
|
||||
- resources.yaml
|
@ -1,40 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: test-rc
|
||||
namespace: test
|
||||
annotations:
|
||||
airshipit.org/initinfra: "workflow"
|
||||
labels:
|
||||
name: test-rc
|
||||
airshipit.org/initinfra: "workflow"
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: test-rc
|
||||
spec:
|
||||
containers:
|
||||
- name: test-rc
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: first-map
|
||||
namespace: target-infra
|
||||
labels:
|
||||
cli-utils.sigs.k8s.io/inventory-id: "some id"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: second-map
|
||||
namespace: target-infra
|
||||
labels:
|
||||
cli-utils.sigs.k8s.io/inventory-id: "some id"
|
||||
|
||||
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubectl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
"k8s.io/kubectl/pkg/cmd/apply"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
)
|
||||
|
||||
// ApplyOptions is a abstraction layer
|
||||
// to ApplyOptions of kubectl/apply package
|
||||
type ApplyOptions struct {
|
||||
ApplyOptions *apply.ApplyOptions
|
||||
}
|
||||
|
||||
// SetDryRun enables/disables the dry run flag in kubectl apply options
|
||||
func (ao *ApplyOptions) SetDryRun(dryRun bool) {
|
||||
if dryRun {
|
||||
// --dry-run is deprecated and can be replaced with --dry-run=client.
|
||||
ao.ApplyOptions.DryRunStrategy = cmdutil.DryRunClient
|
||||
}
|
||||
}
|
||||
|
||||
// SetPrune enables/disables the prune flag in kubectl apply options
|
||||
func (ao *ApplyOptions) SetPrune(label string) {
|
||||
if label != "" {
|
||||
ao.ApplyOptions.Prune = true
|
||||
ao.ApplyOptions.Selector = label
|
||||
} else {
|
||||
ao.ApplyOptions.Prune = false
|
||||
}
|
||||
}
|
||||
|
||||
// SetSourceFiles sets files to read for kubectl apply command
|
||||
func (ao *ApplyOptions) SetSourceFiles(fileNames []string) {
|
||||
ao.ApplyOptions.DeleteOptions.Filenames = fileNames
|
||||
}
|
||||
|
||||
// Run executes the `apply` command.
|
||||
func (ao *ApplyOptions) Run() error {
|
||||
return ao.ApplyOptions.Run()
|
||||
}
|
||||
|
||||
// NewApplyOptions is a helper function that Creates ApplyOptions of kubectl apply module
|
||||
// Values set here, are default, and do not conflict with each other, can be used if you
|
||||
// need `kubectl apply` functionality without calling executing command in shell
|
||||
// To function properly, you may need to specify files from where to read the resources:
|
||||
// SetSourceFiles of returned object has to be used for that
|
||||
func NewApplyOptions(f cmdutil.Factory, streams genericclioptions.IOStreams) (*ApplyOptions, error) {
|
||||
o := apply.NewApplyOptions(streams)
|
||||
o.ServerSideApply = false
|
||||
o.ForceConflicts = false
|
||||
|
||||
o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
|
||||
o.PrintFlags.NamePrintFlags.Operation = operation
|
||||
if o.DryRunStrategy == cmdutil.DryRunClient {
|
||||
err := o.PrintFlags.Complete("%s (dry run)")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if o.DryRunStrategy == cmdutil.DryRunServer {
|
||||
err := o.PrintFlags.Complete("%s (server dry run)")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return o.PrintFlags.ToPrinter()
|
||||
}
|
||||
|
||||
var err error
|
||||
o.Recorder, err = o.RecordFlags.ToRecorder()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dynamicClient, err := f.DynamicClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o.DeleteOptions, err = o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This can only fail if ToDiscoverClient() function fails
|
||||
o.OpenAPISchema, err = f.OpenAPISchema()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o.Validator, err = f.Validator(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o.Builder = f.NewBuilder()
|
||||
o.Mapper, err = f.ToRESTMapper()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o.DynamicClient = dynamicClient
|
||||
|
||||
cl := f.ToRawKubeConfigLoader()
|
||||
if cl == nil {
|
||||
return nil, fmt.Errorf("ToRawKubeConfigLoader() returned nil")
|
||||
}
|
||||
|
||||
o.Namespace, o.EnforceNamespace, err = cl.Namespace()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ApplyOptions{ApplyOptions: o}, nil
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubectl_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/kubectl"
|
||||
k8stest "opendev.org/airship/airshipctl/testutil/k8sutils"
|
||||
)
|
||||
|
||||
var (
|
||||
filenameRC = "testdata/replicationcontroller.yaml"
|
||||
|
||||
testStreams = genericclioptions.NewTestIOStreamsDiscard()
|
||||
ErrDynamicClientError = errors.New("ErrDynamicClientError")
|
||||
ErrValidateError = errors.New("ErrValidateError")
|
||||
ErrToRESTMapperError = errors.New("ErrToRESTMapperError")
|
||||
ErrNamespaceError = errors.New("ErrNamespaceError")
|
||||
)
|
||||
|
||||
func TestNewApplyOptionsFactoryFailures(t *testing.T) {
|
||||
tests := []struct {
|
||||
f cmdutil.Factory
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
f: k8stest.NewMockKubectlFactory().WithDynamicClientByError(nil, ErrDynamicClientError),
|
||||
expectedError: ErrDynamicClientError,
|
||||
},
|
||||
{
|
||||
f: k8stest.NewMockKubectlFactory().WithValidatorByError(nil, ErrValidateError),
|
||||
expectedError: ErrValidateError,
|
||||
},
|
||||
{
|
||||
f: k8stest.NewMockKubectlFactory().WithToRESTMapperByError(nil, ErrToRESTMapperError),
|
||||
expectedError: ErrToRESTMapperError,
|
||||
},
|
||||
{
|
||||
f: k8stest.NewMockKubectlFactory().
|
||||
WithToRawKubeConfigLoaderByError(k8stest.
|
||||
NewMockClientConfig().
|
||||
WithNamespace("", false, ErrNamespaceError)),
|
||||
expectedError: ErrNamespaceError,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
_, err := kubectl.NewApplyOptions(test.f, testStreams)
|
||||
assert.Equal(t, err, test.expectedError)
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubectl
|
||||
|
||||
import (
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
)
|
||||
|
||||
//TODO(sy495p): type name "Interface" is too generic. Use a more specific name
|
||||
|
||||
// Interface provides a abstraction layer built on top of kubectl libraries
|
||||
// to implement kubectl subcommands as kubectl apply
|
||||
type Interface interface {
|
||||
ApplyDocs(docs []document.Document, ao *ApplyOptions) error
|
||||
ApplyYaml(yaml []byte, ao *ApplyOptions) error
|
||||
ApplyOptions() (*ApplyOptions, error)
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubectl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/fs"
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
utilyaml "opendev.org/airship/airshipctl/pkg/util/yaml"
|
||||
)
|
||||
|
||||
// Kubectl container holds Factory, Streams and FileSystem to
|
||||
// interact with upstream kubectl objects and serves as abstraction to kubectl project
|
||||
type Kubectl struct {
|
||||
cmdutil.Factory
|
||||
genericclioptions.IOStreams
|
||||
fs.FileSystem
|
||||
// Directory to buffer documents before passing them to kubectl commands
|
||||
// default is empty, this means that /tmp dir will be used
|
||||
bufferDir string
|
||||
}
|
||||
|
||||
// NewKubectl builds an instance
|
||||
// of Kubectl struct from Path to kubeconfig file
|
||||
func NewKubectl(f cmdutil.Factory) *Kubectl {
|
||||
return &Kubectl{
|
||||
Factory: f,
|
||||
IOStreams: genericclioptions.IOStreams{
|
||||
In: os.Stdin,
|
||||
Out: os.Stdout,
|
||||
ErrOut: os.Stderr,
|
||||
},
|
||||
FileSystem: fs.NewDocumentFs(),
|
||||
}
|
||||
}
|
||||
|
||||
// WithBufferDir sets buffer dir
|
||||
func (kubectl *Kubectl) WithBufferDir(bd string) *Kubectl {
|
||||
kubectl.bufferDir = bd
|
||||
return kubectl
|
||||
}
|
||||
|
||||
// ApplyDocs transform Document into YAML
|
||||
// TODO: (anoskov) Add unit test for ApplyDocs, as of now it is calling ApplyYaml which meets the coverage test.
|
||||
func (kubectl *Kubectl) ApplyDocs(docs []document.Document, ao *ApplyOptions) error {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
for _, doc := range docs {
|
||||
err := utilyaml.WriteOut(buf, doc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return kubectl.ApplyYaml(buf.Bytes(), ao)
|
||||
}
|
||||
|
||||
// ApplyYaml is abstraction to kubectl apply command
|
||||
func (kubectl *Kubectl) ApplyYaml(yaml []byte, ao *ApplyOptions) error {
|
||||
tf, err := kubectl.TempFile(kubectl.bufferDir, config.KubectlTempFilePrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func(f fs.File) {
|
||||
fName := f.Name()
|
||||
dErr := kubectl.RemoveAll(fName)
|
||||
if dErr != nil {
|
||||
log.Fatalf("Failed to cleanup temporary file %s during kubectl apply", fName)
|
||||
}
|
||||
}(tf)
|
||||
|
||||
defer tf.Close()
|
||||
_, err = tf.Write(yaml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ao.SetSourceFiles([]string{tf.Name()})
|
||||
return ao.Run()
|
||||
}
|
||||
|
||||
// ApplyOptions is a wrapper over kubectl ApplyOptions, used to build
|
||||
// new options from the factory and iostreams defined in Kubectl container
|
||||
func (kubectl *Kubectl) ApplyOptions() (*ApplyOptions, error) {
|
||||
return NewApplyOptions(kubectl.Factory, kubectl.IOStreams)
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubectl_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/fs"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/kubectl"
|
||||
k8sutils "opendev.org/airship/airshipctl/pkg/k8s/utils"
|
||||
"opendev.org/airship/airshipctl/testutil"
|
||||
testfs "opendev.org/airship/airshipctl/testutil/fs"
|
||||
k8stest "opendev.org/airship/airshipctl/testutil/k8sutils"
|
||||
)
|
||||
|
||||
var (
|
||||
kubeconfigPath = "testdata/kubeconfig.yaml"
|
||||
fixtureDir = "testdata/"
|
||||
|
||||
ErrWriteOutError = errors.New("ErrWriteOutError")
|
||||
ErrTempFileError = errors.New("ErrTempFileError")
|
||||
)
|
||||
|
||||
func TestNewKubectlFromKubeConfigPath(t *testing.T) {
|
||||
f := k8sutils.FactoryFromKubeConfig(kubeconfigPath, "")
|
||||
kctl := kubectl.NewKubectl(f).WithBufferDir("/tmp/.airship")
|
||||
|
||||
assert.NotNil(t, kctl.Factory)
|
||||
assert.NotNil(t, kctl.FileSystem)
|
||||
assert.NotNil(t, kctl.IOStreams)
|
||||
}
|
||||
|
||||
func TestApply(t *testing.T) {
|
||||
b := testutil.NewTestBundle(t, fixtureDir)
|
||||
docs, err := b.GetByAnnotation("airshipit.org/initinfra")
|
||||
require.NoError(t, err, "failed to get documents from bundle")
|
||||
replicationController, err := b.SelectOne(document.NewSelector().ByKind("ReplicationController"))
|
||||
require.NoError(t, err)
|
||||
rcBytes, err := replicationController.AsYAML()
|
||||
require.NoError(t, err)
|
||||
f := k8stest.FakeFactory(t,
|
||||
[]k8stest.ClientHandler{
|
||||
&k8stest.GenericHandler{
|
||||
Obj: &corev1.ReplicationController{},
|
||||
Bytes: rcBytes,
|
||||
URLPath: "/namespaces/%s/replicationcontrollers",
|
||||
Namespace: replicationController.GetNamespace(),
|
||||
},
|
||||
})
|
||||
defer f.Cleanup()
|
||||
kctl := kubectl.NewKubectl(f).WithBufferDir("/tmp/.airship")
|
||||
kctl.Factory = f
|
||||
ao, err := kctl.ApplyOptions()
|
||||
require.NoError(t, err, "failed to get documents from bundle")
|
||||
ao.SetDryRun(true)
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedErr error
|
||||
fs fs.FileSystem
|
||||
}{
|
||||
{
|
||||
expectedErr: nil,
|
||||
fs: testfs.MockFileSystem{
|
||||
MockRemoveAll: func() error { return nil },
|
||||
MockTempFile: func(string, string) (fs.File, error) {
|
||||
return testfs.TestFile{
|
||||
MockName: func() string { return filenameRC },
|
||||
MockWrite: func([]byte) (int, error) { return 0, nil },
|
||||
MockClose: func() error { return nil },
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedErr: ErrWriteOutError,
|
||||
fs: testfs.MockFileSystem{
|
||||
MockTempFile: func(string, string) (fs.File, error) { return nil, ErrWriteOutError }},
|
||||
},
|
||||
{
|
||||
expectedErr: ErrTempFileError,
|
||||
fs: testfs.MockFileSystem{
|
||||
MockRemoveAll: func() error { return nil },
|
||||
MockTempFile: func(string, string) (fs.File, error) {
|
||||
return testfs.TestFile{
|
||||
MockWrite: func([]byte) (int, error) { return 0, ErrTempFileError },
|
||||
MockName: func() string { return filenameRC },
|
||||
MockClose: func() error { return nil },
|
||||
}, nil
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
kctl.FileSystem = test.fs
|
||||
assert.Equal(t, kctl.ApplyDocs(docs, ao), test.expectedErr)
|
||||
}
|
||||
}
|
19
pkg/k8s/kubectl/testdata/kubeconfig.yaml
vendored
19
pkg/k8s/kubectl/testdata/kubeconfig.yaml
vendored
@ -1,19 +0,0 @@
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNU1Ea3lPVEUzTURNd09Wb1hEVEk1TURreU5qRTNNRE13T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUZyCkdxM0kyb2dZci81Y01Udy9Na1pORTNWQURzdEdyU240WjU2TDhPUGhMcUhDN2t1dno2dVpES3dCSGtGeTBNK2MKRXIzd2piUGE1aTV5NmkyMGtxSHBVMjdPZTA0dzBXV2s4N0RSZVlWaGNoZVJHRXoraWt3SndIcGRmMjJVemZNKwpkSDBzaUhuMVd6UnovYk4za3hMUzJlMnZ2U1Y3bmNubk1YRUd4OXV0MUY0NThHeWxxdmxXTUlWMzg5Q2didXFDCkcwcFdiMTBLM0RVZWdiT25Xa1FmSm5sTWRRVVZDUVdZZEZaaklrcWtkWi9hVTRobkNEV01oZXNWRnFNaDN3VVAKczhQay9BNWh1ZFFPbnFRNDVIWXZLdjZ5RjJWcDUyWExBRUx3NDJ4aVRKZlh0V1h4eHR6cU4wY1lyL2VxeS9XMQp1YVVGSW5xQjFVM0JFL1oxbmFrQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKUUVKQVBLSkFjVDVuK3dsWGJsdU9mS0J3c2gKZTI4R1c5R2QwM0N0NGF3RzhzMXE1ZHNua2tpZmVTUENHVFZ1SXF6UTZDNmJaSk9SMDMvVEl5ejh6NDJnaitDVApjWUZXZkltM2RKTnpRL08xWkdySXZZNWdtcWJtWDlpV0JaU24rRytEOGxubzd2aGMvY0tBRFR5OTMvVU92MThuCkdhMnIrRGJJcHcyTWVBVEl2elpxRS9RWlVSQ25DMmdjUFhTVzFqN2h4R3o1a3ZNcGVDZTdQYVUvdVFvblVHSWsKZ2t6ZzI4NHQvREhUUzc4N1V1SUg5cXBaV09yTFNMOGFBeUxQUHhWSXBteGZmbWRETE9TS2VUemRlTmxoSitUMwowQlBVaHBQTlJBNTNJN0hRQjhVUDR2elNONTkzZ1VFbVlFQ2Jic2RYSzB6ZVR6SDdWWHR2Zmd5WTVWWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
server: https://10.0.1.7:6443
|
||||
name: kubernetes_target
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kubernetes_target
|
||||
user: kubernetes-admin
|
||||
name: kubernetes-admin@kubernetes
|
||||
current-context: ""
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kubernetes-admin
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
|
2
pkg/k8s/kubectl/testdata/kustomization.yaml
vendored
2
pkg/k8s/kubectl/testdata/kustomization.yaml
vendored
@ -1,2 +0,0 @@
|
||||
resources:
|
||||
- replicationcontroller.yaml
|
@ -1,22 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: test-rc
|
||||
namespace: test
|
||||
annotations:
|
||||
airshipit.org/initinfra: "workflow"
|
||||
labels:
|
||||
name: test-rc
|
||||
airshipit.org/initinfra: "workflow"
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: test-rc
|
||||
spec:
|
||||
containers:
|
||||
- name: test-rc
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
@ -1,246 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package poller_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/clusterreader"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
"sigs.k8s.io/cli-utils/pkg/testutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/poller"
|
||||
)
|
||||
|
||||
var (
|
||||
deploymentGVK = appsv1.SchemeGroupVersion.WithKind("Deployment")
|
||||
rsGVK = appsv1.SchemeGroupVersion.WithKind("ReplicaSet")
|
||||
podGVK = v1.SchemeGroupVersion.WithKind("Pod")
|
||||
)
|
||||
|
||||
// gkNamespace contains information about a GroupVersionKind and a namespace.
|
||||
type gkNamespace struct {
|
||||
GroupKind schema.GroupKind
|
||||
Namespace string
|
||||
}
|
||||
|
||||
func TestSync(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
identifiers []object.ObjMetadata
|
||||
expectedSynced []gkNamespace
|
||||
}{
|
||||
"no identifiers": {
|
||||
identifiers: []object.ObjMetadata{},
|
||||
},
|
||||
"same GVK in multiple namespaces": {
|
||||
identifiers: []object.ObjMetadata{
|
||||
{
|
||||
GroupKind: deploymentGVK.GroupKind(),
|
||||
Name: "deployment",
|
||||
Namespace: "Foo",
|
||||
},
|
||||
{
|
||||
GroupKind: deploymentGVK.GroupKind(),
|
||||
Name: "deployment",
|
||||
Namespace: "Bar",
|
||||
},
|
||||
},
|
||||
expectedSynced: []gkNamespace{
|
||||
{
|
||||
GroupKind: deploymentGVK.GroupKind(),
|
||||
Namespace: "Foo",
|
||||
},
|
||||
{
|
||||
GroupKind: rsGVK.GroupKind(),
|
||||
Namespace: "Foo",
|
||||
},
|
||||
{
|
||||
GroupKind: podGVK.GroupKind(),
|
||||
Namespace: "Foo",
|
||||
},
|
||||
{
|
||||
GroupKind: deploymentGVK.GroupKind(),
|
||||
Namespace: "Bar",
|
||||
},
|
||||
{
|
||||
GroupKind: rsGVK.GroupKind(),
|
||||
Namespace: "Bar",
|
||||
},
|
||||
{
|
||||
GroupKind: podGVK.GroupKind(),
|
||||
Namespace: "Bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
fakeMapper := testutil.NewFakeRESTMapper(
|
||||
appsv1.SchemeGroupVersion.WithKind("Deployment"),
|
||||
appsv1.SchemeGroupVersion.WithKind("ReplicaSet"),
|
||||
v1.SchemeGroupVersion.WithKind("Pod"),
|
||||
)
|
||||
|
||||
for tn, tc := range testCases {
|
||||
t.Run(tn, func(t *testing.T) {
|
||||
fakeReader := &fakeReader{}
|
||||
|
||||
cr, err := clusterreader.NewCachingClusterReader(fakeReader, fakeMapper, tc.identifiers)
|
||||
require.NoError(t, err)
|
||||
|
||||
clusterReader := &poller.CachingClusterReader{Cr: cr}
|
||||
err = clusterReader.Sync(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
synced := fakeReader.syncedGVKNamespaces
|
||||
sortGVKNamespaces(synced)
|
||||
expectedSynced := tc.expectedSynced
|
||||
sortGVKNamespaces(expectedSynced)
|
||||
require.Equal(t, expectedSynced, synced)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSync_Errors(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
mapper meta.RESTMapper
|
||||
readerError error
|
||||
expectSyncError bool
|
||||
cacheError bool
|
||||
cacheErrorText string
|
||||
}{
|
||||
"mapping and reader are successful": {
|
||||
mapper: testutil.NewFakeRESTMapper(
|
||||
apiextv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"),
|
||||
),
|
||||
readerError: nil,
|
||||
expectSyncError: false,
|
||||
cacheError: false,
|
||||
},
|
||||
"reader returns NotFound error": {
|
||||
mapper: testutil.NewFakeRESTMapper(
|
||||
apiextv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"),
|
||||
),
|
||||
readerError: errors.NewNotFound(schema.GroupResource{
|
||||
Group: "apiextensions.k8s.io",
|
||||
Resource: "customresourcedefinitions",
|
||||
}, "my-crd"),
|
||||
expectSyncError: false,
|
||||
cacheError: true,
|
||||
cacheErrorText: "not found",
|
||||
},
|
||||
"reader returns request timed out other error": {
|
||||
mapper: testutil.NewFakeRESTMapper(
|
||||
apiextv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"),
|
||||
),
|
||||
readerError: errors.NewInternalError(fmt.Errorf("request timed out")),
|
||||
expectSyncError: false,
|
||||
cacheError: true,
|
||||
cacheErrorText: "not found",
|
||||
},
|
||||
"reader returns other error": {
|
||||
mapper: testutil.NewFakeRESTMapper(
|
||||
apiextv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"),
|
||||
),
|
||||
readerError: errors.NewInternalError(fmt.Errorf("testing")),
|
||||
expectSyncError: true,
|
||||
cacheError: true,
|
||||
cacheErrorText: "not found",
|
||||
},
|
||||
"mapping not found": {
|
||||
mapper: testutil.NewFakeRESTMapper(),
|
||||
expectSyncError: false,
|
||||
cacheError: true,
|
||||
cacheErrorText: "no matches for kind",
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range testCases {
|
||||
t.Run(tn, func(t *testing.T) {
|
||||
identifiers := []object.ObjMetadata{
|
||||
{
|
||||
Name: "my-crd",
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "apiextensions.k8s.io",
|
||||
Kind: "CustomResourceDefinition",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
fakeReader := &fakeReader{
|
||||
err: tc.readerError,
|
||||
}
|
||||
|
||||
cr, err := clusterreader.NewCachingClusterReader(fakeReader, tc.mapper, identifiers)
|
||||
require.NoError(t, err)
|
||||
clusterReader := poller.CachingClusterReader{Cr: cr}
|
||||
|
||||
err = clusterReader.Sync(context.Background())
|
||||
|
||||
if tc.expectSyncError {
|
||||
require.Equal(t, tc.readerError, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func sortGVKNamespaces(gvkNamespaces []gkNamespace) {
|
||||
sort.Slice(gvkNamespaces, func(i, j int) bool {
|
||||
if gvkNamespaces[i].GroupKind.String() != gvkNamespaces[j].GroupKind.String() {
|
||||
return gvkNamespaces[i].GroupKind.String() < gvkNamespaces[j].GroupKind.String()
|
||||
}
|
||||
return gvkNamespaces[i].Namespace < gvkNamespaces[j].Namespace
|
||||
})
|
||||
}
|
||||
|
||||
type fakeReader struct {
|
||||
syncedGVKNamespaces []gkNamespace
|
||||
err error
|
||||
}
|
||||
|
||||
func (f *fakeReader) Get(_ context.Context, _ client.ObjectKey, _ client.Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//nolint:gocritic
|
||||
func (f *fakeReader) List(_ context.Context, list client.ObjectList, opts ...client.ListOption) error {
|
||||
var namespace string
|
||||
for _, opt := range opts {
|
||||
switch opt := opt.(type) {
|
||||
case client.InNamespace:
|
||||
namespace = string(opt)
|
||||
}
|
||||
}
|
||||
|
||||
gvk := list.GetObjectKind().GroupVersionKind()
|
||||
f.syncedGVKNamespaces = append(f.syncedGVKNamespaces, gkNamespace{
|
||||
GroupKind: gvk.GroupKind(),
|
||||
Namespace: namespace,
|
||||
})
|
||||
|
||||
return f.err
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package poller_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/poller"
|
||||
)
|
||||
|
||||
func TestNewExpression(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
condition string
|
||||
value string
|
||||
obj map[string]interface{}
|
||||
expectedResult bool
|
||||
expectedErrString string
|
||||
}{
|
||||
{
|
||||
name: "Success - value matched",
|
||||
condition: "{.status}",
|
||||
obj: map[string]interface{}{"status": "provisioned"},
|
||||
value: "provisioned",
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "Success - empty value",
|
||||
condition: "{.status}",
|
||||
obj: map[string]interface{}{"status": "provisioned"},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "Failed - invalid condition",
|
||||
condition: "{*%.status}",
|
||||
expectedErrString: "unrecognized character in action",
|
||||
},
|
||||
{
|
||||
name: "Failed - path not found in object",
|
||||
condition: "{.status}",
|
||||
expectedErrString: "status is not found",
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
tt := test
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
exp := poller.Expression{
|
||||
Condition: tt.condition,
|
||||
Value: tt.value,
|
||||
}
|
||||
|
||||
res, err := exp.Match(tt.obj)
|
||||
assert.Equal(t, tt.expectedResult, res)
|
||||
if test.expectedErrString != "" {
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), test.expectedErrString)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -1,318 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package poller_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubectl/pkg/validation"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/engine"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||
kstatustestutil "sigs.k8s.io/cli-utils/pkg/kstatus/polling/testutil"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
"sigs.k8s.io/cli-utils/pkg/testutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/poller"
|
||||
)
|
||||
|
||||
func TestNewStatusPoller(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
factory cmdutil.Factory
|
||||
expectedError bool
|
||||
}{
|
||||
"failed rest config": {
|
||||
factory: &MockCmdUtilFactory{MockToRESTConfig: func() (*rest.Config, error) {
|
||||
return nil, errors.New("rest config error")
|
||||
}},
|
||||
expectedError: true,
|
||||
},
|
||||
"failed rest mapper": {
|
||||
factory: &MockCmdUtilFactory{MockToRESTConfig: func() (*rest.Config, error) {
|
||||
return nil, nil
|
||||
},
|
||||
MockToRESTMapper: func() (meta.RESTMapper, error) {
|
||||
return nil, errors.New("rest mapper error")
|
||||
}},
|
||||
expectedError: true,
|
||||
},
|
||||
"failed new client": {
|
||||
factory: &MockCmdUtilFactory{MockToRESTConfig: func() (*rest.Config, error) {
|
||||
return nil, nil
|
||||
},
|
||||
MockToRESTMapper: func() (meta.RESTMapper, error) {
|
||||
return nil, nil
|
||||
}},
|
||||
expectedError: true,
|
||||
},
|
||||
"success new poller": {
|
||||
factory: &MockCmdUtilFactory{MockToRESTConfig: func() (*rest.Config, error) {
|
||||
return &rest.Config{}, nil
|
||||
},
|
||||
MockToRESTMapper: func() (meta.RESTMapper, error) {
|
||||
return testutil.NewFakeRESTMapper(), nil
|
||||
}},
|
||||
expectedError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range testCases {
|
||||
t.Run(tn, func(t *testing.T) {
|
||||
p, err := poller.NewStatusPoller(tc.factory)
|
||||
if tc.expectedError {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, p)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatusPollerRun(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
identifiers []object.ObjMetadata
|
||||
ClusterReaderFactoryFunc engine.ClusterReaderFactoryFunc
|
||||
StatusReadersFactoryFunc engine.StatusReadersFactoryFunc
|
||||
defaultStatusReader engine.StatusReader
|
||||
expectedEventTypes []event.EventType
|
||||
}{
|
||||
"single resource": {
|
||||
identifiers: []object.ObjMetadata{
|
||||
{
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "apps",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
Name: "foo",
|
||||
Namespace: "bar",
|
||||
},
|
||||
},
|
||||
defaultStatusReader: &fakeStatusReader{
|
||||
resourceStatuses: map[schema.GroupKind][]status.Status{
|
||||
schema.GroupKind{Group: "apps", Kind: "Deployment"}: { //nolint:gofmt
|
||||
status.InProgressStatus,
|
||||
status.CurrentStatus,
|
||||
},
|
||||
},
|
||||
resourceStatusCount: make(map[schema.GroupKind]int),
|
||||
},
|
||||
expectedEventTypes: []event.EventType{
|
||||
event.ResourceUpdateEvent,
|
||||
event.ResourceUpdateEvent,
|
||||
},
|
||||
ClusterReaderFactoryFunc: func(_ client.Reader, _ meta.RESTMapper, _ []object.ObjMetadata) (
|
||||
engine.ClusterReader, error) {
|
||||
return kstatustestutil.NewNoopClusterReader(), nil
|
||||
},
|
||||
StatusReadersFactoryFunc: func(_ engine.ClusterReader, _ meta.RESTMapper) (
|
||||
statusReaders map[schema.GroupKind]engine.StatusReader, defaultStatusReader engine.StatusReader) {
|
||||
return make(map[schema.GroupKind]engine.StatusReader), &fakeStatusReader{
|
||||
resourceStatuses: map[schema.GroupKind][]status.Status{
|
||||
schema.GroupKind{Group: "apps", Kind: "Deployment"}: { //nolint:gofmt
|
||||
status.InProgressStatus,
|
||||
status.CurrentStatus,
|
||||
},
|
||||
},
|
||||
resourceStatusCount: make(map[schema.GroupKind]int),
|
||||
}
|
||||
},
|
||||
},
|
||||
"multiple resources": {
|
||||
identifiers: []object.ObjMetadata{
|
||||
{
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "apps",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
{
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Service",
|
||||
},
|
||||
Name: "bar",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
ClusterReaderFactoryFunc: func(_ client.Reader, _ meta.RESTMapper, _ []object.ObjMetadata) (
|
||||
engine.ClusterReader, error) {
|
||||
return kstatustestutil.NewNoopClusterReader(), nil
|
||||
},
|
||||
StatusReadersFactoryFunc: func(_ engine.ClusterReader, _ meta.RESTMapper) (
|
||||
statusReaders map[schema.GroupKind]engine.StatusReader, defaultStatusReader engine.StatusReader) {
|
||||
return make(map[schema.GroupKind]engine.StatusReader), &fakeStatusReader{
|
||||
resourceStatuses: map[schema.GroupKind][]status.Status{
|
||||
schema.GroupKind{Group: "apps", Kind: "Deployment"}: { //nolint:gofmt
|
||||
status.InProgressStatus,
|
||||
status.CurrentStatus,
|
||||
},
|
||||
schema.GroupKind{Group: "", Kind: "Service"}: { //nolint:gofmt
|
||||
status.InProgressStatus,
|
||||
status.InProgressStatus,
|
||||
status.CurrentStatus,
|
||||
},
|
||||
},
|
||||
resourceStatusCount: make(map[schema.GroupKind]int),
|
||||
}
|
||||
},
|
||||
expectedEventTypes: []event.EventType{
|
||||
event.ResourceUpdateEvent,
|
||||
event.ResourceUpdateEvent,
|
||||
event.ResourceUpdateEvent,
|
||||
event.ResourceUpdateEvent,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range testCases {
|
||||
t.Run(tn, func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
identifiers := tc.identifiers
|
||||
|
||||
fakeMapper := testutil.NewFakeRESTMapper(
|
||||
appsv1.SchemeGroupVersion.WithKind("Deployment"),
|
||||
v1.SchemeGroupVersion.WithKind("Service"),
|
||||
)
|
||||
|
||||
e := poller.StatusPoller{
|
||||
ClusterReaderFactoryFunc: tc.ClusterReaderFactoryFunc,
|
||||
StatusReadersFactoryFunc: tc.StatusReadersFactoryFunc,
|
||||
Engine: &engine.PollerEngine{Mapper: fakeMapper},
|
||||
}
|
||||
|
||||
options := polling.Options{PollInterval: time.Second, UseCache: true}
|
||||
|
||||
eventChannel := e.Poll(ctx, identifiers, options)
|
||||
|
||||
var eventTypes []event.EventType
|
||||
for ch := range eventChannel {
|
||||
eventTypes = append(eventTypes, ch.EventType)
|
||||
if len(eventTypes) == len(tc.expectedEventTypes) {
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
require.Equal(t, tc.expectedEventTypes, eventTypes)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeStatusReader struct {
|
||||
resourceStatuses map[schema.GroupKind][]status.Status
|
||||
resourceStatusCount map[schema.GroupKind]int
|
||||
}
|
||||
|
||||
func (f *fakeStatusReader) ReadStatus(_ context.Context, identifier object.ObjMetadata) *event.ResourceStatus {
|
||||
count := f.resourceStatusCount[identifier.GroupKind]
|
||||
resourceStatusSlice := f.resourceStatuses[identifier.GroupKind]
|
||||
var resourceStatus status.Status
|
||||
if len(resourceStatusSlice) > count {
|
||||
resourceStatus = resourceStatusSlice[count]
|
||||
} else {
|
||||
resourceStatus = resourceStatusSlice[len(resourceStatusSlice)-1]
|
||||
}
|
||||
f.resourceStatusCount[identifier.GroupKind] = count + 1
|
||||
return &event.ResourceStatus{
|
||||
Identifier: identifier,
|
||||
Status: resourceStatus,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *fakeStatusReader) ReadStatusForObject(_ context.Context, _ *unstructured.Unstructured) *event.ResourceStatus {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ cmdutil.Factory = &MockCmdUtilFactory{}
|
||||
|
||||
type MockCmdUtilFactory struct {
|
||||
MockToRESTConfig func() (*rest.Config, error)
|
||||
MockToRESTMapper func() (meta.RESTMapper, error)
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) ToRESTConfig() (*rest.Config, error) {
|
||||
return n.MockToRESTConfig()
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) ToRESTMapper() (meta.RESTMapper, error) {
|
||||
return n.MockToRESTMapper()
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) ToRawKubeConfigLoader() clientcmd.ClientConfig {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) DynamicClient() (dynamic.Interface, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) RESTClient() (*rest.RESTClient, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) NewBuilder() *resource.Builder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) ClientForMapping(_ *meta.RESTMapping) (resource.RESTClient, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) UnstructuredClientForMapping(_ *meta.RESTMapping) (resource.RESTClient, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) Validator(_ bool) (validation.Schema, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) OpenAPISchema() (openapi.Resources, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (n *MockCmdUtilFactory) OpenAPIGetter() discovery.OpenAPISchemaInterface {
|
||||
return nil
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package poller_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/testutil"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
fakemapper "sigs.k8s.io/cli-utils/pkg/testutil"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/poller"
|
||||
)
|
||||
|
||||
var (
|
||||
customGVK = schema.GroupVersionKind{
|
||||
Group: "custom.io",
|
||||
Version: "v1beta1",
|
||||
Kind: "Custom",
|
||||
}
|
||||
name = "Foo"
|
||||
namespace = "default"
|
||||
)
|
||||
|
||||
func TestGenericStatusReader(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
result *status.Result
|
||||
err error
|
||||
expectedIdentifier object.ObjMetadata
|
||||
expectedStatus status.Status
|
||||
condMap map[schema.GroupKind]poller.Expression
|
||||
}{
|
||||
"successfully computes status": {
|
||||
result: &status.Result{
|
||||
Status: status.InProgressStatus,
|
||||
Message: "this is a test",
|
||||
},
|
||||
expectedIdentifier: object.ObjMetadata{
|
||||
GroupKind: customGVK.GroupKind(),
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
expectedStatus: status.InProgressStatus,
|
||||
},
|
||||
"successfully computes custom status": {
|
||||
result: &status.Result{
|
||||
Status: status.CurrentStatus,
|
||||
Message: "this is a test",
|
||||
},
|
||||
expectedIdentifier: object.ObjMetadata{
|
||||
GroupKind: customGVK.GroupKind(),
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
condMap: map[schema.GroupKind]poller.Expression{
|
||||
customGVK.GroupKind(): {Condition: "{.metadata.name}", Value: "Bar"}},
|
||||
expectedStatus: status.InProgressStatus,
|
||||
},
|
||||
"computing status fails": {
|
||||
err: fmt.Errorf("this error is a test"),
|
||||
expectedIdentifier: object.ObjMetadata{
|
||||
GroupKind: customGVK.GroupKind(),
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
expectedStatus: status.UnknownStatus,
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range testCases {
|
||||
t.Run(tn, func(t *testing.T) {
|
||||
fakeReader := testutil.NewNoopClusterReader()
|
||||
fakeMapper := fakemapper.NewFakeRESTMapper()
|
||||
|
||||
resourceStatusReader := &poller.CustomResourceReader{
|
||||
Reader: fakeReader,
|
||||
Mapper: fakeMapper,
|
||||
StatusFunc: func(u *unstructured.Unstructured) (*status.Result, error) {
|
||||
return tc.result, tc.err
|
||||
},
|
||||
CondMap: tc.condMap,
|
||||
}
|
||||
|
||||
o := &unstructured.Unstructured{}
|
||||
o.SetGroupVersionKind(customGVK)
|
||||
o.SetName(name)
|
||||
o.SetNamespace(namespace)
|
||||
|
||||
resourceStatus := resourceStatusReader.ReadStatusForObject(context.Background(), o)
|
||||
|
||||
require.Equal(t, tc.expectedIdentifier, resourceStatus.Identifier)
|
||||
require.Equal(t, tc.expectedStatus, resourceStatus.Status)
|
||||
})
|
||||
}
|
||||
}
|
19
pkg/k8s/utils/testdata/kubeconfig.yaml
vendored
19
pkg/k8s/utils/testdata/kubeconfig.yaml
vendored
@ -1,19 +0,0 @@
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNU1Ea3lPVEUzTURNd09Wb1hEVEk1TURreU5qRTNNRE13T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUZyCkdxM0kyb2dZci81Y01Udy9Na1pORTNWQURzdEdyU240WjU2TDhPUGhMcUhDN2t1dno2dVpES3dCSGtGeTBNK2MKRXIzd2piUGE1aTV5NmkyMGtxSHBVMjdPZTA0dzBXV2s4N0RSZVlWaGNoZVJHRXoraWt3SndIcGRmMjJVemZNKwpkSDBzaUhuMVd6UnovYk4za3hMUzJlMnZ2U1Y3bmNubk1YRUd4OXV0MUY0NThHeWxxdmxXTUlWMzg5Q2didXFDCkcwcFdiMTBLM0RVZWdiT25Xa1FmSm5sTWRRVVZDUVdZZEZaaklrcWtkWi9hVTRobkNEV01oZXNWRnFNaDN3VVAKczhQay9BNWh1ZFFPbnFRNDVIWXZLdjZ5RjJWcDUyWExBRUx3NDJ4aVRKZlh0V1h4eHR6cU4wY1lyL2VxeS9XMQp1YVVGSW5xQjFVM0JFL1oxbmFrQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKUUVKQVBLSkFjVDVuK3dsWGJsdU9mS0J3c2gKZTI4R1c5R2QwM0N0NGF3RzhzMXE1ZHNua2tpZmVTUENHVFZ1SXF6UTZDNmJaSk9SMDMvVEl5ejh6NDJnaitDVApjWUZXZkltM2RKTnpRL08xWkdySXZZNWdtcWJtWDlpV0JaU24rRytEOGxubzd2aGMvY0tBRFR5OTMvVU92MThuCkdhMnIrRGJJcHcyTWVBVEl2elpxRS9RWlVSQ25DMmdjUFhTVzFqN2h4R3o1a3ZNcGVDZTdQYVUvdVFvblVHSWsKZ2t6ZzI4NHQvREhUUzc4N1V1SUg5cXBaV09yTFNMOGFBeUxQUHhWSXBteGZmbWRETE9TS2VUemRlTmxoSitUMwowQlBVaHBQTlJBNTNJN0hRQjhVUDR2elNONTkzZ1VFbVlFQ2Jic2RYSzB6ZVR6SDdWWHR2Zmd5WTVWWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
server: https://10.0.1.7:6443
|
||||
name: kubernetes_target
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kubernetes_target
|
||||
user: kubernetes-admin
|
||||
name: kubernetes-admin@kubernetes
|
||||
current-context: ""
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kubernetes-admin
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
|
@ -1,2 +0,0 @@
|
||||
resources:
|
||||
- replicationcontroller.yaml
|
@ -1,22 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: test-rc
|
||||
namespace: test
|
||||
annotations:
|
||||
airshipit.org/initinfra: "workflow"
|
||||
labels:
|
||||
name: test-rc
|
||||
airshipit.org/initinfra: "workflow"
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: test-rc
|
||||
spec:
|
||||
containers:
|
||||
- name: test-rc
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
@ -15,19 +15,8 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"sigs.k8s.io/cli-utils/pkg/manifestreader"
|
||||
"sigs.k8s.io/cli-utils/pkg/util/factory"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
)
|
||||
|
||||
// ClientOption is a function that allows to modify ConfigFlags object which is used to create Client
|
||||
@ -50,68 +39,5 @@ func FactoryFromKubeConfig(path, context string, opts ...ClientOption) cmdutil.F
|
||||
o(kf)
|
||||
}
|
||||
|
||||
return cmdutil.NewFactory(cmdutil.NewMatchVersionFlags(&factory.CachingRESTClientGetter{
|
||||
Delegate: kf,
|
||||
}))
|
||||
}
|
||||
|
||||
// Streams returns default IO streams object, like stdout, stdin, stderr
|
||||
func Streams() genericclioptions.IOStreams {
|
||||
return genericclioptions.IOStreams{
|
||||
In: os.Stdin,
|
||||
Out: os.Stdout,
|
||||
ErrOut: os.Stderr,
|
||||
}
|
||||
}
|
||||
|
||||
// ManifestReaderFactory factory function for manifestreader.ManifestReader
|
||||
type ManifestReaderFactory func(
|
||||
validate bool,
|
||||
bundle document.Bundle,
|
||||
mapper meta.RESTMapper) manifestreader.ManifestReader
|
||||
|
||||
// DefaultManifestReaderFactory default factory function for manifestreader.ManifestReader
|
||||
var DefaultManifestReaderFactory ManifestReaderFactory = func(
|
||||
validate bool,
|
||||
bundle document.Bundle,
|
||||
mapper meta.RESTMapper) manifestreader.ManifestReader {
|
||||
return NewManifestBundleReader(validate, bundle, mapper)
|
||||
}
|
||||
|
||||
// NewManifestBundleReader returns implementation of manifestreader interface
|
||||
func NewManifestBundleReader(
|
||||
validate bool,
|
||||
bundle document.Bundle,
|
||||
mapper meta.RESTMapper) *ManifestBundleReader {
|
||||
opts := manifestreader.ReaderOptions{
|
||||
Mapper: mapper,
|
||||
Validate: validate,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
}
|
||||
buffer := bytes.NewBuffer([]byte{})
|
||||
return &ManifestBundleReader{
|
||||
Bundle: bundle,
|
||||
writer: buffer,
|
||||
StreamReader: &manifestreader.StreamManifestReader{
|
||||
ReaderName: "airship",
|
||||
Reader: buffer,
|
||||
ReaderOptions: opts,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ManifestBundleReader implements manifestreader interface that to transform bundle to slice
|
||||
// of *resource.Info objects using Read() method.
|
||||
type ManifestBundleReader struct {
|
||||
Bundle document.Bundle
|
||||
StreamReader *manifestreader.StreamManifestReader
|
||||
writer io.Writer
|
||||
}
|
||||
|
||||
func (mbr *ManifestBundleReader) Read() ([]*unstructured.Unstructured, error) {
|
||||
err := mbr.Bundle.Write(mbr.writer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mbr.StreamReader.Read()
|
||||
return cmdutil.NewFactory(cmdutil.NewMatchVersionFlags(kf))
|
||||
}
|
||||
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
)
|
||||
|
||||
func TestDefaultManifestFactory(t *testing.T) {
|
||||
bundle, err := document.NewBundleByPath("testdata/source_bundle")
|
||||
require.NoError(t, err)
|
||||
mapper, err := FactoryFromKubeConfig("testdata/kubeconfig.yaml", "", SetTimeout("30s")).ToRESTMapper()
|
||||
require.NoError(t, err)
|
||||
reader := DefaultManifestReaderFactory(false, bundle, mapper)
|
||||
require.NotNil(t, reader)
|
||||
}
|
||||
|
||||
func TestManifestBundleReader(t *testing.T) {
|
||||
bundle, err := document.NewBundleByPath("testdata/source_bundle")
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
name string
|
||||
errString string
|
||||
|
||||
reader io.Reader
|
||||
writer io.Writer
|
||||
}{
|
||||
{
|
||||
name: "Replication Controller Read Successfully",
|
||||
},
|
||||
{
|
||||
name: "Read error",
|
||||
errString: "failed to read from bundle",
|
||||
reader: fakeReaderWriter{
|
||||
readErr: fmt.Errorf("failed to read from bundle"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Write error",
|
||||
errString: "failed to write bundle",
|
||||
writer: fakeReaderWriter{
|
||||
writeErr: fmt.Errorf("failed to write bundle"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mapper, err := FactoryFromKubeConfig("testdata/kubeconfig.yaml", "").ToRESTMapper()
|
||||
require.NoError(t, err)
|
||||
reader := NewManifestBundleReader(false, bundle, mapper)
|
||||
if tt.reader != nil {
|
||||
reader.StreamReader.Reader = tt.reader
|
||||
}
|
||||
if tt.writer != nil {
|
||||
reader.writer = tt.writer
|
||||
}
|
||||
objects, err := reader.Read()
|
||||
if tt.errString != "" {
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), tt.errString)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, objects, 1)
|
||||
gvk := objects[0].GetObjectKind().GroupVersionKind()
|
||||
assert.Equal(t, gvk, schema.GroupVersionKind{
|
||||
Kind: "ReplicationController",
|
||||
Group: "",
|
||||
Version: "v1"})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeReaderWriter struct {
|
||||
readErr error
|
||||
writeErr error
|
||||
}
|
||||
|
||||
var _ io.Reader = fakeReaderWriter{}
|
||||
var _ io.Writer = fakeReaderWriter{}
|
||||
|
||||
func (f fakeReaderWriter) Read(p []byte) (n int, err error) {
|
||||
return 0, f.readErr
|
||||
}
|
||||
|
||||
func (f fakeReaderWriter) Write(p []byte) (n int, err error) {
|
||||
return 0, f.writeErr
|
||||
}
|
@ -28,7 +28,6 @@ import (
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/kubeconfig"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/utils"
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/errors"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/executors"
|
||||
@ -389,5 +388,5 @@ func (c *client) PhaseByAPIObj(phaseObj *v1alpha1.Phase) (ifc.Phase, error) {
|
||||
}
|
||||
|
||||
func defaultProcessor() events.EventProcessor {
|
||||
return events.NewDefaultProcessor(utils.Streams())
|
||||
return events.NewDefaultProcessor()
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
phaseerrors "opendev.org/airship/airshipctl/pkg/phase/errors"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/ifc"
|
||||
"opendev.org/airship/airshipctl/pkg/util"
|
||||
"opendev.org/airship/airshipctl/pkg/util/yaml"
|
||||
)
|
||||
|
||||
@ -105,7 +106,7 @@ func (c *ListCommand) RunE() error {
|
||||
return err
|
||||
}
|
||||
if c.OutputFormat == TableOutputFormat {
|
||||
return PrintPhaseListTable(c.Writer, phaseList)
|
||||
return util.PrintObjects(phaseList, util.PhaseListFormat, c.Writer, false)
|
||||
}
|
||||
return yaml.WriteOut(c.Writer, phaseList)
|
||||
}
|
||||
@ -192,14 +193,10 @@ func (c *PlanListCommand) RunE() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch {
|
||||
case c.Options.FormatType == YamlOutputFormat:
|
||||
if c.Options.FormatType == YamlOutputFormat {
|
||||
return yaml.WriteOut(c.Writer, phasePlans)
|
||||
case c.Options.FormatType == TableOutputFormat:
|
||||
return PrintPlanListTable(c.Writer, phasePlans)
|
||||
default:
|
||||
return PrintPlanListTable(c.Writer, phasePlans)
|
||||
}
|
||||
return util.PrintObjects(phasePlans, util.PlanListFormat, c.Writer, false)
|
||||
}
|
||||
|
||||
// PlanRunFlags options for phase run command
|
||||
|
@ -110,12 +110,8 @@ func TestRunCommand(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestListCommand(t *testing.T) {
|
||||
outputString1 := "NAMESPACE RESOURCE CLUSTER " +
|
||||
"NAME EXECUTOR DOC ENTRYPOINT " +
|
||||
" "
|
||||
outputString2 := " Phase/phase ephemeral" +
|
||||
"-cluster KubernetesApply ephemeral/phase " +
|
||||
" "
|
||||
outputString1 := "NAMESPACE NAME CLUSTER NAME EXECUTOR DOC ENTRYPOINT"
|
||||
outputString2 := " phase ephemeral-cluster KubernetesApply ephemeral/phase"
|
||||
yamlOutput := `---
|
||||
- apiVersion: airshipit.org/v1alpha1
|
||||
config:
|
||||
@ -367,7 +363,6 @@ func TestPlanListCommand(t *testing.T) {
|
||||
Format: "table",
|
||||
expectedOut: [][]byte{{}},
|
||||
},
|
||||
|
||||
{
|
||||
name: "List phases",
|
||||
factory: func() (*config.Config, error) {
|
||||
@ -379,13 +374,8 @@ func TestPlanListCommand(t *testing.T) {
|
||||
return conf, nil
|
||||
},
|
||||
expectedOut: [][]byte{
|
||||
[]byte("NAMESPACE RESOURCE DESCRIPTION " +
|
||||
" " +
|
||||
" "),
|
||||
[]byte(" PhasePlan/phasePlan Default phase plan" +
|
||||
" " +
|
||||
" " +
|
||||
" "),
|
||||
[]byte("NAMESPACE NAME DESCRIPTION"),
|
||||
[]byte(" phasePlan Default phase plan"),
|
||||
{},
|
||||
},
|
||||
Format: "table",
|
||||
@ -659,7 +649,7 @@ func TestValidateCommand(t *testing.T) {
|
||||
return conf, nil
|
||||
},
|
||||
errContains: `document filtered by selector [Group="airshipit.org", Version="v1alpha1", ` +
|
||||
`Kind="GenericContainer", Name="document-validation"] found no documents`,
|
||||
`Kind="GenericContainer", Name="applier"] found no documents`,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@ import (
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
inventoryifc "opendev.org/airship/airshipctl/pkg/inventory/ifc"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/utils"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/executors"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/ifc"
|
||||
testdoc "opendev.org/airship/airshipctl/testutil/document"
|
||||
@ -151,7 +150,7 @@ func TestBMHExecutorRun(t *testing.T) {
|
||||
go func() {
|
||||
executor.Run(ch, tt.runOptions)
|
||||
}()
|
||||
processor := events.NewDefaultProcessor(utils.Streams())
|
||||
processor := events.NewDefaultProcessor()
|
||||
defer processor.Close()
|
||||
err = processor.Process(ch)
|
||||
if tt.expectedErr != "" {
|
||||
|
@ -15,22 +15,19 @@
|
||||
package executors
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"time"
|
||||
"os"
|
||||
|
||||
"sigs.k8s.io/cli-utils/pkg/common"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/aggregator"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||
"sigs.k8s.io/cli-utils/pkg/provider"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
|
||||
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/cluster/clustermap"
|
||||
"opendev.org/airship/airshipctl/pkg/container"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
airerrors "opendev.org/airship/airshipctl/pkg/errors"
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
k8sapplier "opendev.org/airship/airshipctl/pkg/k8s/applier"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/kubeconfig"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/utils"
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/errors"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/ifc"
|
||||
@ -43,12 +40,14 @@ type KubeApplierExecutor struct {
|
||||
ExecutorBundle document.Bundle
|
||||
ExecutorDocument document.Document
|
||||
BundleName string
|
||||
targetPath string
|
||||
|
||||
apiObject *airshipv1.KubernetesApply
|
||||
cleanup kubeconfig.Cleanup
|
||||
clusterMap clustermap.ClusterMap
|
||||
clusterName string
|
||||
kubeconfig kubeconfig.Interface
|
||||
clientFunc container.ClientV1Alpha1FactoryFunc
|
||||
execObj *airshipv1.GenericContainer
|
||||
}
|
||||
|
||||
// NewKubeApplierExecutor returns instance of executor
|
||||
@ -63,6 +62,22 @@ func NewKubeApplierExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
doc, err := cfg.PhaseConfigBundle.SelectOne(document.NewApplierContainerExecutorSelector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cObj := airshipv1.DefaultGenericContainer()
|
||||
err = doc.ToAPIObject(cObj, airshipv1.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clientFunc := container.NewClientV1Alpha1
|
||||
if cfg.ContainerFunc != nil {
|
||||
clientFunc = cfg.ContainerFunc
|
||||
}
|
||||
|
||||
return &KubeApplierExecutor{
|
||||
ExecutorBundle: bundle,
|
||||
BundleName: cfg.PhaseName,
|
||||
@ -71,9 +86,9 @@ func NewKubeApplierExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
|
||||
clusterMap: cfg.ClusterMap,
|
||||
clusterName: cfg.ClusterName,
|
||||
kubeconfig: cfg.KubeConfig,
|
||||
// default cleanup that does nothing
|
||||
// replaced with a meaningful cleanup while preparing kubeconfig
|
||||
cleanup: func() {},
|
||||
clientFunc: clientFunc,
|
||||
execObj: cObj,
|
||||
targetPath: cfg.TargetPath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -81,55 +96,78 @@ func NewKubeApplierExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
|
||||
func (e *KubeApplierExecutor) Run(ch chan events.Event, runOpts ifc.RunOptions) {
|
||||
defer close(ch)
|
||||
|
||||
applier, filteredBundle, err := e.prepareApplier(ch)
|
||||
e.apiObject.Config.Debug = log.DebugEnabled()
|
||||
e.apiObject.Config.PhaseName = e.BundleName
|
||||
|
||||
if e.apiObject.Config.Kubeconfig == "" {
|
||||
kcfg, ctx, cleanup, err := e.getKubeconfig()
|
||||
if err != nil {
|
||||
handleError(ch, err)
|
||||
return
|
||||
}
|
||||
defer cleanup()
|
||||
e.apiObject.Config.Kubeconfig, e.apiObject.Config.Context = kcfg, ctx
|
||||
}
|
||||
e.execObj.Spec.StorageMounts = append(e.execObj.Spec.StorageMounts, airshipv1.StorageMount{
|
||||
MountType: "bind",
|
||||
Src: e.apiObject.Config.Kubeconfig,
|
||||
DstPath: e.apiObject.Config.Kubeconfig,
|
||||
ReadWriteMode: false,
|
||||
})
|
||||
log.Printf("using kubeconfig at '%s' and context '%s'", e.apiObject.Config.Kubeconfig, e.apiObject.Config.Context)
|
||||
|
||||
e.apiObject.Config.DryRun = runOpts.DryRun
|
||||
if runOpts.Timeout != nil {
|
||||
e.apiObject.Config.WaitOptions.Timeout = int(*runOpts.Timeout)
|
||||
}
|
||||
|
||||
reader, err := e.prepareDocuments()
|
||||
if err != nil {
|
||||
handleError(ch, err)
|
||||
return
|
||||
}
|
||||
defer e.cleanup()
|
||||
|
||||
dryRunStrategy := common.DryRunNone
|
||||
if runOpts.DryRun {
|
||||
dryRunStrategy = common.DryRunClient
|
||||
opts, err := yaml.Marshal(&e.apiObject.Config)
|
||||
if err != nil {
|
||||
handleError(ch, err)
|
||||
return
|
||||
}
|
||||
timeout := time.Second * time.Duration(e.apiObject.Config.WaitOptions.Timeout)
|
||||
if runOpts.Timeout != nil {
|
||||
timeout = *runOpts.Timeout
|
||||
}
|
||||
pollInterval := time.Second * time.Duration(e.apiObject.Config.WaitOptions.PollInterval)
|
||||
|
||||
log.Debugf("WaitTimeout: %v", timeout)
|
||||
applyOptions := k8sapplier.ApplyOptions{
|
||||
DryRunStrategy: dryRunStrategy,
|
||||
Prune: e.apiObject.Config.PruneOptions.Prune,
|
||||
BundleName: e.BundleName,
|
||||
WaitTimeout: timeout,
|
||||
PollInterval: pollInterval,
|
||||
e.execObj.Config = string(opts)
|
||||
err = e.clientFunc("", reader, os.Stdout, e.execObj, e.targetPath).Run()
|
||||
if err != nil {
|
||||
handleError(ch, err)
|
||||
return
|
||||
}
|
||||
applier.ApplyBundle(filteredBundle, applyOptions)
|
||||
}
|
||||
|
||||
func (e *KubeApplierExecutor) prepareApplier(ch chan events.Event) (*k8sapplier.Applier, document.Bundle, error) {
|
||||
log.Debug("Filtering out documents that shouldn't be applied to kubernetes from document bundle")
|
||||
bundle, err := e.ExecutorBundle.SelectBundle(document.NewDeployToK8sSelector())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
func (e *KubeApplierExecutor) getKubeconfig() (string, string, func(), error) {
|
||||
log.Debug("Getting kubeconfig context name from cluster map")
|
||||
context, err := e.clusterMap.ClusterKubeconfigContext(e.clusterName)
|
||||
ctx, err := e.clusterMap.ClusterKubeconfigContext(e.clusterName)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return "", "", nil, err
|
||||
}
|
||||
log.Debug("Getting kubeconfig file information from kubeconfig provider")
|
||||
path, cleanup, err := e.kubeconfig.GetFile()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return "", "", nil, err
|
||||
}
|
||||
// set up cleanup only if all calls up to here were successful
|
||||
e.cleanup = cleanup
|
||||
log.Printf("Using kubeconfig at '%s' and context '%s'", path, context)
|
||||
factory := utils.FactoryFromKubeConfig(path, context)
|
||||
return k8sapplier.NewApplier(ch, factory, e.apiObject.Config.WaitOptions.Conditions), bundle, nil
|
||||
return path, ctx, cleanup, nil
|
||||
}
|
||||
|
||||
func (e *KubeApplierExecutor) prepareDocuments() (io.Reader, error) {
|
||||
log.Debug("Filtering out documents that shouldn't be applied to kubernetes from document bundle")
|
||||
filteredBundle, err := e.ExecutorBundle.SelectBundle(document.NewDeployToK8sSelector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = filteredBundle.Write(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf, err
|
||||
}
|
||||
|
||||
// Validate document set
|
||||
@ -158,42 +196,6 @@ func (e *KubeApplierExecutor) Render(w io.Writer, o ifc.RenderOptions) error {
|
||||
}
|
||||
|
||||
// Status returns the status of the given phase
|
||||
func (e *KubeApplierExecutor) Status() (sts ifc.ExecutorStatus, err error) {
|
||||
var ctx string
|
||||
ctx, err = e.clusterMap.ClusterKubeconfigContext(e.clusterName)
|
||||
if err != nil {
|
||||
return sts, err
|
||||
}
|
||||
log.Debug("Getting kubeconfig file information from kubeconfig provider")
|
||||
path, cleanup, err := e.kubeconfig.GetFile()
|
||||
if err != nil {
|
||||
return sts, err
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
cf := provider.NewProvider(utils.FactoryFromKubeConfig(path, ctx))
|
||||
rm, err := cf.Factory().ToRESTMapper()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r := utils.DefaultManifestReaderFactory(false, e.ExecutorBundle, rm)
|
||||
infos, err := r.Read()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var resSts event.ResourceStatuses
|
||||
|
||||
for _, info := range infos {
|
||||
s, sErr := status.Compute(info)
|
||||
if sErr != nil {
|
||||
return
|
||||
}
|
||||
st := &event.ResourceStatus{
|
||||
Status: s.Status,
|
||||
}
|
||||
resSts = append(resSts, st)
|
||||
}
|
||||
_ = aggregator.AggregateStatus(resSts, status.CurrentStatus)
|
||||
return ifc.ExecutorStatus{}, err
|
||||
func (e *KubeApplierExecutor) Status() (ifc.ExecutorStatus, error) {
|
||||
return ifc.ExecutorStatus{}, airerrors.ErrNotImplemented{What: KubernetesApply}
|
||||
}
|
||||
|
@ -26,11 +26,11 @@ import (
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/cluster/clustermap"
|
||||
"opendev.org/airship/airshipctl/pkg/container"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
"opendev.org/airship/airshipctl/pkg/fs"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/kubeconfig"
|
||||
"opendev.org/airship/airshipctl/pkg/k8s/utils"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/executors"
|
||||
"opendev.org/airship/airshipctl/pkg/phase/ifc"
|
||||
testdoc "opendev.org/airship/airshipctl/testutil/document"
|
||||
@ -49,39 +49,6 @@ config:
|
||||
timeout: 600
|
||||
pruneOptions:
|
||||
prune: false
|
||||
`
|
||||
ValidExecutorDocNamespaced = `apiVersion: airshipit.org/v1alpha1
|
||||
kind: KubernetesApply
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/deploy-k8s: "false"
|
||||
name: kubernetes-apply-namespaced
|
||||
namespace: bundle
|
||||
config:
|
||||
waitOptions:
|
||||
timeout: 600
|
||||
pruneOptions:
|
||||
prune: false
|
||||
`
|
||||
testValidKubeconfig = `apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: ca-data
|
||||
server: https://10.0.1.7:6443
|
||||
name: kubernetes_target
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kubernetes_target
|
||||
user: kubernetes-admin
|
||||
name: kubernetes-admin@kubernetes
|
||||
current-context: ""
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kubernetes-admin
|
||||
user:
|
||||
client-certificate-data: cert-data
|
||||
client-key-data: client-keydata
|
||||
`
|
||||
WrongExecutorDoc = `apiVersion: v1
|
||||
kind: ConfigMap
|
||||
@ -90,6 +57,18 @@ metadata:
|
||||
namespace: default
|
||||
labels:
|
||||
cli-utils.sigs.k8s.io/inventory-id: "some id"
|
||||
`
|
||||
applierKRMDoc = `---
|
||||
apiVersion: airshipit.org/v1alpha1
|
||||
kind: GenericContainer
|
||||
metadata:
|
||||
name: applier
|
||||
labels:
|
||||
airshipit.org/deploy-k8s: "false"
|
||||
spec:
|
||||
type: krm
|
||||
image: quay.io/airshipit/applier:latest
|
||||
hostNetwork: true
|
||||
`
|
||||
)
|
||||
|
||||
@ -125,11 +104,41 @@ func testApplierBundleFactory(t *testing.T, filteredContent string, writer io.Wr
|
||||
}
|
||||
}
|
||||
|
||||
func testApplierBundleFactoryFilterError() document.BundleFactoryFunc {
|
||||
func testApplierBundleFactorySelectBundleError() document.BundleFactoryFunc {
|
||||
return func() (document.Bundle, error) {
|
||||
bundle := &testdoc.MockBundle{}
|
||||
bundle.On("SelectOne", mock.Anything).
|
||||
Return(nil, nil)
|
||||
bundle.On("SelectBundle", mock.Anything).
|
||||
Return(nil, errors.New("error"))
|
||||
Return(nil, errors.New("error selecting bundle"))
|
||||
return bundle, nil
|
||||
}
|
||||
}
|
||||
|
||||
func testApplierBundleFactoryWriteError() document.BundleFactoryFunc {
|
||||
return func() (document.Bundle, error) {
|
||||
bundle := &testdoc.MockBundle{}
|
||||
filteredBundle := &testdoc.MockBundle{}
|
||||
bundle.On("SelectOne", mock.Anything).
|
||||
Return(nil, nil)
|
||||
filteredBundle.On("Write", mock.Anything).
|
||||
Return(errors.New("error writing bundle"))
|
||||
bundle.On("SelectBundle", mock.Anything).
|
||||
Return(filteredBundle, nil)
|
||||
return bundle, nil
|
||||
}
|
||||
}
|
||||
|
||||
func testApplierBundleFactoryNoError() document.BundleFactoryFunc {
|
||||
return func() (document.Bundle, error) {
|
||||
bundle := &testdoc.MockBundle{}
|
||||
filteredBundle := &testdoc.MockBundle{}
|
||||
bundle.On("SelectOne", mock.Anything).
|
||||
Return(nil, nil)
|
||||
filteredBundle.On("Write", mock.Anything).
|
||||
Return(nil)
|
||||
bundle.On("SelectBundle", mock.Anything).
|
||||
Return(filteredBundle, nil)
|
||||
return bundle, nil
|
||||
}
|
||||
}
|
||||
@ -156,23 +165,31 @@ func TestNewKubeApplierExecutor(t *testing.T) {
|
||||
execDoc document.Document
|
||||
expectedErr bool
|
||||
bundleFactory document.BundleFactoryFunc
|
||||
phaseBundle document.Bundle
|
||||
}{
|
||||
{
|
||||
name: "valid executor",
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
bundleFactory: testdoc.EmptyBundleFactory,
|
||||
},
|
||||
{
|
||||
name: "wrong executor document",
|
||||
name: "invalid executor document",
|
||||
execDoc: executorDoc(t, WrongExecutorDoc),
|
||||
expectedErr: true,
|
||||
},
|
||||
|
||||
{
|
||||
name: "bundle factory returns an error",
|
||||
name: "invalid bundle factory",
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
expectedErr: true,
|
||||
bundleFactory: testdoc.ErrorBundleFactory,
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid phase config bundle",
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
bundleFactory: testdoc.EmptyBundleFactory,
|
||||
phaseBundle: executorBundle(t, ""),
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "valid phase config bundle",
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
bundleFactory: testdoc.EmptyBundleFactory,
|
||||
phaseBundle: executorBundle(t, applierKRMDoc),
|
||||
},
|
||||
}
|
||||
|
||||
@ -181,8 +198,9 @@ func TestNewKubeApplierExecutor(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
exec, err := executors.NewKubeApplierExecutor(
|
||||
ifc.ExecutorConfig{
|
||||
ExecutorDocument: tt.execDoc,
|
||||
BundleFactory: tt.bundleFactory,
|
||||
ExecutorDocument: tt.execDoc,
|
||||
BundleFactory: tt.bundleFactory,
|
||||
PhaseConfigBundle: tt.phaseBundle,
|
||||
})
|
||||
if tt.expectedErr {
|
||||
require.Error(t, err)
|
||||
@ -209,13 +227,42 @@ func TestKubeApplierExecutorRun(t *testing.T) {
|
||||
execDoc document.Document
|
||||
bundleFactory document.BundleFactoryFunc
|
||||
clusterMap clustermap.ClusterMap
|
||||
clientFunc container.ClientV1Alpha1FactoryFunc
|
||||
}{
|
||||
{
|
||||
name: "cant read kubeconfig error",
|
||||
containsErr: "no such file or directory",
|
||||
name: "unable to get kubeconfig context",
|
||||
containsErr: "cluster 'foo' is not defined in cluster map",
|
||||
bundleFactory: testApplierBundleFactory(t, "", nil),
|
||||
kubeconf: testKubeconfig(`invalid kubeconfig`),
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
clusterName: "foo",
|
||||
clusterMap: clustermap.NewClusterMap(&v1alpha1.ClusterMap{
|
||||
Map: map[string]*v1alpha1.Cluster{
|
||||
"ephemeral-cluster": {},
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "unable to get kubeconfig file",
|
||||
containsErr: "failed to get kubeconfig",
|
||||
bundleFactory: testApplierBundleFactory(t, "", nil),
|
||||
kubeconf: fakeKubeConfig{getFile: func() (string, kubeconfig.Cleanup, error) {
|
||||
return "", nil, errors.New("failed to get kubeconfig")
|
||||
}},
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
clusterName: "ephemeral-cluster",
|
||||
clusterMap: clustermap.NewClusterMap(&v1alpha1.ClusterMap{
|
||||
Map: map[string]*v1alpha1.Cluster{
|
||||
"ephemeral-cluster": {},
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "unable to select bundle",
|
||||
containsErr: "error selecting bundle",
|
||||
bundleFactory: testApplierBundleFactorySelectBundleError(),
|
||||
kubeconf: testKubeconfig("kubeconfig"),
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
clusterName: "ephemeral-cluster",
|
||||
clusterMap: clustermap.NewClusterMap(&v1alpha1.ClusterMap{
|
||||
Map: map[string]*v1alpha1.Cluster{
|
||||
@ -224,18 +271,55 @@ func TestKubeApplierExecutorRun(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "error cluster not defined",
|
||||
containsErr: "is not defined in cluster map",
|
||||
bundleFactory: testApplierBundleFactory(t, "", nil),
|
||||
kubeconf: testKubeconfig(testValidKubeconfig),
|
||||
name: "unable to write bundle",
|
||||
containsErr: "error writing bundle",
|
||||
bundleFactory: testApplierBundleFactoryWriteError(),
|
||||
kubeconf: testKubeconfig("kubeconfig"),
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
clusterMap: clustermap.NewClusterMap(v1alpha1.DefaultClusterMap()),
|
||||
clusterName: "ephemeral-cluster",
|
||||
clusterMap: clustermap.NewClusterMap(&v1alpha1.ClusterMap{
|
||||
Map: map[string]*v1alpha1.Cluster{
|
||||
"ephemeral-cluster": {},
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "error during executor bundle filtering",
|
||||
containsErr: "error",
|
||||
name: "unsuccessful run",
|
||||
containsErr: "applier failure",
|
||||
bundleFactory: testApplierBundleFactoryNoError(),
|
||||
kubeconf: testKubeconfig("kubeconfig"),
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
bundleFactory: testApplierBundleFactoryFilterError(),
|
||||
clusterName: "ephemeral-cluster",
|
||||
clusterMap: clustermap.NewClusterMap(&v1alpha1.ClusterMap{
|
||||
Map: map[string]*v1alpha1.Cluster{
|
||||
"ephemeral-cluster": {},
|
||||
},
|
||||
}),
|
||||
clientFunc: func(_ string, _ io.Reader, _ io.Writer,
|
||||
_ *v1alpha1.GenericContainer, _ string) container.ClientV1Alpha1 {
|
||||
return MockClientFuncInterface{MockRun: func() error {
|
||||
return errors.New("applier failure")
|
||||
}}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "successful run",
|
||||
containsErr: "",
|
||||
bundleFactory: testApplierBundleFactoryNoError(),
|
||||
kubeconf: testKubeconfig("kubeconfig"),
|
||||
execDoc: executorDoc(t, ValidExecutorDoc),
|
||||
clusterName: "ephemeral-cluster",
|
||||
clusterMap: clustermap.NewClusterMap(&v1alpha1.ClusterMap{
|
||||
Map: map[string]*v1alpha1.Cluster{
|
||||
"ephemeral-cluster": {},
|
||||
},
|
||||
}),
|
||||
clientFunc: func(_ string, _ io.Reader, _ io.Writer,
|
||||
_ *v1alpha1.GenericContainer, _ string) container.ClientV1Alpha1 {
|
||||
return MockClientFuncInterface{MockRun: func() error {
|
||||
return nil
|
||||
}}
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@ -243,17 +327,19 @@ func TestKubeApplierExecutorRun(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
exec, err := executors.NewKubeApplierExecutor(
|
||||
ifc.ExecutorConfig{
|
||||
ExecutorDocument: tt.execDoc,
|
||||
BundleFactory: tt.bundleFactory,
|
||||
KubeConfig: tt.kubeconf,
|
||||
ClusterMap: tt.clusterMap,
|
||||
ClusterName: tt.clusterName,
|
||||
ExecutorDocument: tt.execDoc,
|
||||
BundleFactory: tt.bundleFactory,
|
||||
KubeConfig: tt.kubeconf,
|
||||
ClusterMap: tt.clusterMap,
|
||||
ClusterName: tt.clusterName,
|
||||
PhaseConfigBundle: executorBundle(t, applierKRMDoc),
|
||||
ContainerFunc: tt.clientFunc,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, exec)
|
||||
ch := make(chan events.Event)
|
||||
go exec.Run(ch, ifc.RunOptions{})
|
||||
processor := events.NewDefaultProcessor(utils.Streams())
|
||||
processor := events.NewDefaultProcessor()
|
||||
err = processor.Process(ch)
|
||||
if tt.containsErr != "" {
|
||||
require.Error(t, err)
|
||||
@ -269,8 +355,9 @@ func TestRender(t *testing.T) {
|
||||
writer := bytes.NewBuffer([]byte{})
|
||||
content := "Some content"
|
||||
exec, err := executors.NewKubeApplierExecutor(ifc.ExecutorConfig{
|
||||
BundleFactory: testApplierBundleFactory(t, content, writer),
|
||||
ExecutorDocument: executorDoc(t, ValidExecutorDoc),
|
||||
BundleFactory: testApplierBundleFactory(t, content, writer),
|
||||
ExecutorDocument: executorDoc(t, ValidExecutorDoc),
|
||||
PhaseConfigBundle: executorBundle(t, applierKRMDoc),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, exec)
|
||||
@ -328,9 +415,10 @@ func TestKubeApplierExecutor_Validate(t *testing.T) {
|
||||
tt := test
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
e, err := executors.NewKubeApplierExecutor(ifc.ExecutorConfig{
|
||||
BundleFactory: tt.bundleFactory,
|
||||
PhaseName: tt.bundleName,
|
||||
ExecutorDocument: executorDoc(t, ValidExecutorDoc),
|
||||
BundleFactory: tt.bundleFactory,
|
||||
PhaseName: tt.bundleName,
|
||||
ExecutorDocument: executorDoc(t, ValidExecutorDoc),
|
||||
PhaseConfigBundle: executorBundle(t, applierKRMDoc),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, e)
|
||||
|
@ -48,11 +48,6 @@ type RenderOptions struct {
|
||||
FilterSelector document.Selector
|
||||
}
|
||||
|
||||
// WaitOptions holds only timeout now, but may be extended in the future
|
||||
type WaitOptions struct {
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
// ExecutorFactory for executor instantiation
|
||||
type ExecutorFactory func(config ExecutorConfig) (Executor, error)
|
||||
|
||||
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package phase
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/util"
|
||||
|
||||
"sigs.k8s.io/cli-utils/pkg/print/table"
|
||||
)
|
||||
|
||||
//PrintPhaseListTable prints phase list table
|
||||
func PrintPhaseListTable(w io.Writer, phases []*v1alpha1.Phase) error {
|
||||
rt, err := util.NewResourceTable(phases, util.DefaultStatusFunction())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printer := util.DefaultTablePrinter(w, nil)
|
||||
clusternameCol := table.ColumnDef{
|
||||
ColumnName: "clustername",
|
||||
ColumnHeader: "CLUSTER NAME",
|
||||
ColumnWidth: 20,
|
||||
PrintResourceFunc: func(w io.Writer, width int, r table.Resource) (int,
|
||||
error) {
|
||||
phase, err := phaseFromResource(r)
|
||||
if err != nil {
|
||||
return 0, nil
|
||||
}
|
||||
txt := phase.ClusterName
|
||||
if len(txt) > width {
|
||||
txt = txt[:width]
|
||||
}
|
||||
_, err = fmt.Fprintf(w, txt)
|
||||
return len(txt), err
|
||||
},
|
||||
}
|
||||
executorrefkindCol := table.ColumnDef{
|
||||
ColumnName: "executorrefkind",
|
||||
ColumnHeader: "EXECUTOR",
|
||||
ColumnWidth: 20,
|
||||
PrintResourceFunc: func(w io.Writer, width int, r table.Resource) (int,
|
||||
error) {
|
||||
phase, err := phaseFromResource(r)
|
||||
if err != nil {
|
||||
return 0, nil
|
||||
}
|
||||
txt := phase.Config.ExecutorRef.Kind
|
||||
if len(txt) > width {
|
||||
txt = txt[:width]
|
||||
}
|
||||
_, err = fmt.Fprintf(w, txt)
|
||||
return len(txt), err
|
||||
},
|
||||
}
|
||||
docentrypointCol := table.ColumnDef{
|
||||
ColumnName: "docentrypoint",
|
||||
ColumnHeader: "DOC ENTRYPOINT",
|
||||
ColumnWidth: 100,
|
||||
PrintResourceFunc: func(w io.Writer, width int, r table.Resource) (int,
|
||||
error) {
|
||||
phase, err := phaseFromResource(r)
|
||||
if err != nil {
|
||||
return 0, nil
|
||||
}
|
||||
txt := phase.Config.DocumentEntryPoint
|
||||
if len(txt) > width {
|
||||
txt = txt[:width]
|
||||
}
|
||||
_, err = fmt.Fprintf(w, txt)
|
||||
return len(txt), err
|
||||
},
|
||||
}
|
||||
printer.Columns = append(printer.Columns, clusternameCol, executorrefkindCol, docentrypointCol)
|
||||
printer.PrintTable(rt, 0)
|
||||
return nil
|
||||
}
|
||||
|
||||
func phaseFromResource(r table.Resource) (*v1alpha1.Phase, error) {
|
||||
rs := r.ResourceStatus()
|
||||
if rs == nil {
|
||||
return nil, errors.New("Resource status is nil")
|
||||
}
|
||||
phase := &v1alpha1.Phase{}
|
||||
return phase, runtime.DefaultUnstructuredConverter.FromUnstructured(rs.Resource.Object, phase)
|
||||
}
|
||||
|
||||
//PrintPlanListTable prints plan list table
|
||||
func PrintPlanListTable(w io.Writer, phasePlans []*v1alpha1.PhasePlan) error {
|
||||
rt, err := util.NewResourceTable(phasePlans, util.DefaultStatusFunction())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printer := util.DefaultTablePrinter(w, nil)
|
||||
descriptionCol := table.ColumnDef{
|
||||
ColumnName: "description",
|
||||
ColumnHeader: "DESCRIPTION",
|
||||
ColumnWidth: 200,
|
||||
PrintResourceFunc: func(w io.Writer, width int, r table.Resource) (int, error) {
|
||||
rs := r.ResourceStatus()
|
||||
if rs == nil {
|
||||
return 0, nil
|
||||
}
|
||||
plan := &v1alpha1.PhasePlan{}
|
||||
err := runtime.DefaultUnstructuredConverter.FromUnstructured(rs.Resource.Object, plan)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
txt := plan.Description
|
||||
if len(txt) > width {
|
||||
txt = txt[:width]
|
||||
}
|
||||
_, err = fmt.Fprintf(w, txt)
|
||||
return len(txt), err
|
||||
},
|
||||
}
|
||||
printer.Columns = append(printer.Columns, descriptionCol)
|
||||
printer.PrintTable(rt, 0)
|
||||
return nil
|
||||
}
|
@ -1,180 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package phase
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/util"
|
||||
)
|
||||
|
||||
func TestPrintPhaseListTable(t *testing.T) {
|
||||
phases := []*v1alpha1.Phase{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Phase",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "p1",
|
||||
ClusterName: "cluster",
|
||||
},
|
||||
Config: v1alpha1.PhaseConfig{
|
||||
DocumentEntryPoint: "test",
|
||||
ExecutorRef: &v1.ObjectReference{Kind: "test"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
phases []*v1alpha1.Phase
|
||||
wantPanic bool
|
||||
}{
|
||||
{
|
||||
name: "success",
|
||||
phases: phases,
|
||||
wantPanic: false,
|
||||
},
|
||||
{
|
||||
name: "phase with no executor ref",
|
||||
phases: []*v1alpha1.Phase{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Pe",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "p1",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPanic: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
w := &bytes.Buffer{}
|
||||
defer func() {
|
||||
r := recover()
|
||||
if (r != nil) != tt.wantPanic {
|
||||
t.Errorf("should have panic")
|
||||
}
|
||||
}()
|
||||
err := PrintPhaseListTable(w, tt.phases)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNonPrintable(t *testing.T) {
|
||||
_, err := util.NewResourceTable("non Printable string", util.DefaultStatusFunction())
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDefaultStatusFunction(t *testing.T) {
|
||||
f := util.DefaultStatusFunction()
|
||||
expectedObj := map[string]interface{}{
|
||||
"kind": "Phase",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "p1",
|
||||
"creationTimestamp": nil,
|
||||
},
|
||||
"config": map[string]interface{}{
|
||||
"documentEntryPoint": "",
|
||||
"executorRef": map[string]interface{}{
|
||||
"kind": "test",
|
||||
},
|
||||
"validation": map[string]interface{}{},
|
||||
},
|
||||
}
|
||||
printable := &v1alpha1.Phase{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Phase",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "p1",
|
||||
},
|
||||
Config: v1alpha1.PhaseConfig{
|
||||
ExecutorRef: &v1.ObjectReference{Kind: "test"},
|
||||
},
|
||||
}
|
||||
rs := f(printable)
|
||||
assert.Equal(t, expectedObj, rs.Resource.Object)
|
||||
}
|
||||
|
||||
func TestPrintPlanListTable(t *testing.T) {
|
||||
plans := []*v1alpha1.PhasePlan{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "PhasePlan",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "p",
|
||||
},
|
||||
Description: "description",
|
||||
Phases: []v1alpha1.PhaseStep{
|
||||
{
|
||||
Name: "phase",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
plans []*v1alpha1.PhasePlan
|
||||
}{
|
||||
{
|
||||
name: "Success print plan list",
|
||||
plans: plans,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
w := &bytes.Buffer{}
|
||||
err := PrintPlanListTable(w, tt.plans)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultStatusFunctionForPhasePlan(t *testing.T) {
|
||||
f := util.DefaultStatusFunction()
|
||||
expectedObj := map[string]interface{}{
|
||||
"kind": "PhasePlan",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "p1",
|
||||
"creationTimestamp": nil,
|
||||
},
|
||||
"validation": map[string]interface{}{},
|
||||
}
|
||||
printable := &v1alpha1.PhasePlan{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "PhasePlan",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "p1",
|
||||
},
|
||||
}
|
||||
rs := f(printable)
|
||||
assert.Equal(t, expectedObj, rs.Resource.Object)
|
||||
}
|
@ -99,17 +99,6 @@ func TestRender(t *testing.T) {
|
||||
},
|
||||
expErr: fmt.Errorf("unable to parse requirement: found '(', expected: identifier"),
|
||||
},
|
||||
{
|
||||
name: "Malformed Label",
|
||||
settings: &phase.RenderCommand{
|
||||
Label: "app=(",
|
||||
Source: phase.RenderSourceExecutor,
|
||||
PhaseID: ifc.ID{
|
||||
Name: fixturePath,
|
||||
},
|
||||
},
|
||||
expErr: fmt.Errorf("unable to parse requirement: found '(', expected: identifier"),
|
||||
},
|
||||
{
|
||||
name: "source doesn't exist",
|
||||
settings: &phase.RenderCommand{
|
||||
|
@ -15,138 +15,66 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
pe "sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
"sigs.k8s.io/cli-utils/pkg/print/table"
|
||||
"k8s.io/kubectl/pkg/cmd/get"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
)
|
||||
|
||||
// Printable is an object which has Group, Version, Kind, Name and Namespace
|
||||
// fields and appropriate methods to retrieve them. All K8s api objects
|
||||
// implement methods above
|
||||
type Printable interface {
|
||||
metav1.Object
|
||||
runtime.Object
|
||||
const (
|
||||
// PhaseListFormat is used to print tables with phase list
|
||||
PhaseListFormat = "NAMESPACE:metadata.namespace,NAME:metadata.name,CLUSTER NAME:metadata.clusterName," +
|
||||
"EXECUTOR:config.executorRef.kind,DOC ENTRYPOINT:config.documentEntryPoint"
|
||||
// PlanListFormat is used to print tables with plan list
|
||||
PlanListFormat = "NAMESPACE:metadata.namespace,NAME:metadata.name,DESCRIPTION:description"
|
||||
)
|
||||
|
||||
// PrintObjects prints suitable
|
||||
func PrintObjects(objects interface{}, template string, w io.Writer, noHeaders bool) error {
|
||||
tabWriter := GetNewTabWriter(w)
|
||||
defer tabWriter.Flush()
|
||||
|
||||
p, err := get.NewCustomColumnsPrinterFromSpec(template,
|
||||
scheme.Codecs.UniversalDecoder(scheme.Scheme.PrioritizedVersionsAllGroups()...), noHeaders)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, obj := range runtimeObjectsConverter(objects) {
|
||||
if err := p.PrintObj(obj, tabWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ table.ResourceStates = &ResourceTable{}
|
||||
|
||||
// ResourceTable provides information about the resources that should be printed
|
||||
type ResourceTable struct {
|
||||
resources []Printable
|
||||
statusFunc PrintStatusFunction
|
||||
}
|
||||
|
||||
// NewResourceTable creates resource status table
|
||||
func NewResourceTable(object interface{}, statusFunc PrintStatusFunction) (*ResourceTable, error) {
|
||||
var resources []Printable
|
||||
func runtimeObjectsConverter(object interface{}) []runtime.Object {
|
||||
var resources []runtime.Object
|
||||
if object == nil {
|
||||
return resources
|
||||
}
|
||||
value := reflect.ValueOf(object)
|
||||
switch value.Kind() {
|
||||
case reflect.Slice:
|
||||
resources = make([]Printable, value.Len())
|
||||
resources = make([]runtime.Object, value.Len())
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
printable, ok := value.Index(i).Interface().(Printable)
|
||||
printable, ok := value.Index(i).Interface().(runtime.Object)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("resource %#v is not printable", value.Index(i).Interface())
|
||||
log.Debugf("resource %#v is not printable, skipping", value.Index(i).Interface())
|
||||
continue
|
||||
}
|
||||
resources[i] = printable
|
||||
}
|
||||
default:
|
||||
res, ok := value.Interface().(Printable)
|
||||
res, ok := value.Interface().(runtime.Object)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("resource %#v is not printable", value.Interface())
|
||||
}
|
||||
resources = []Printable{res}
|
||||
}
|
||||
|
||||
return &ResourceTable{
|
||||
resources: resources,
|
||||
statusFunc: statusFunc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Resources list of table rows
|
||||
func (rt *ResourceTable) Resources() []table.Resource {
|
||||
result := make([]table.Resource, len(rt.resources))
|
||||
for i, obj := range rt.resources {
|
||||
result[i] = &resource{Printable: obj, statusFunc: rt.statusFunc}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
//Error returns error for resource table
|
||||
func (rt *ResourceTable) Error() error {
|
||||
return fmt.Errorf("error table printing")
|
||||
}
|
||||
|
||||
var _ table.Resource = &resource{}
|
||||
|
||||
type resource struct {
|
||||
Printable
|
||||
statusFunc PrintStatusFunction
|
||||
}
|
||||
|
||||
// Identifier opf the resource
|
||||
func (r *resource) Identifier() object.ObjMetadata {
|
||||
return object.ObjMetadata{
|
||||
Namespace: r.GetNamespace(),
|
||||
Name: r.GetName(),
|
||||
GroupKind: r.GetObjectKind().GroupVersionKind().GroupKind(),
|
||||
}
|
||||
}
|
||||
|
||||
// ResourceStatus returns resource status object
|
||||
func (r *resource) ResourceStatus() *PrintResourceStatus {
|
||||
return r.statusFunc(r.Printable)
|
||||
}
|
||||
|
||||
// SubResources list of subresources
|
||||
func (r *resource) SubResources() []table.Resource {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultTablePrinter returns basic table printer with 2 columns: Namespace
|
||||
// and Name/Kind
|
||||
func DefaultTablePrinter(out, errOut io.Writer) *table.BaseTablePrinter {
|
||||
cols := []table.ColumnDefinition{
|
||||
table.MustColumn("namespace"),
|
||||
table.MustColumn("resource"),
|
||||
}
|
||||
return &table.BaseTablePrinter{
|
||||
IOStreams: genericclioptions.IOStreams{
|
||||
Out: out,
|
||||
ErrOut: errOut,
|
||||
},
|
||||
Columns: cols,
|
||||
}
|
||||
}
|
||||
|
||||
// PrintResourceStatus alias for ResourceStatus
|
||||
type PrintResourceStatus = pe.ResourceStatus
|
||||
|
||||
// PrintStatusFunction alias for status function
|
||||
type PrintStatusFunction = func(Printable) *PrintResourceStatus
|
||||
|
||||
// DefaultStatusFunction for resource status
|
||||
func DefaultStatusFunction() PrintStatusFunction {
|
||||
return func(obj Printable) *PrintResourceStatus {
|
||||
unsContent, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
|
||||
identifier := object.ObjMetadata{
|
||||
Namespace: obj.GetNamespace(),
|
||||
Name: obj.GetName(),
|
||||
GroupKind: obj.GetObjectKind().GroupVersionKind().GroupKind(),
|
||||
}
|
||||
return &PrintResourceStatus{
|
||||
Identifier: identifier,
|
||||
Resource: &unstructured.Unstructured{Object: unsContent},
|
||||
Error: err,
|
||||
log.Debugf("resource %#v is not printable, skipping", value.Interface())
|
||||
}
|
||||
resources = []runtime.Object{res}
|
||||
}
|
||||
return resources
|
||||
}
|
||||
|
@ -16,94 +16,67 @@ package util_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
airapiv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||
"opendev.org/airship/airshipctl/pkg/util"
|
||||
)
|
||||
|
||||
func TestPrintTableForList(t *testing.T) {
|
||||
resources := []*airapiv1.Phase{
|
||||
func TestNewTabPrinter(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
objects interface{}
|
||||
template string
|
||||
noHeaders bool
|
||||
expected string
|
||||
errorStr string
|
||||
}{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Phase",
|
||||
name: "nil object",
|
||||
template: "NAME:name",
|
||||
},
|
||||
{
|
||||
name: "no template defined",
|
||||
errorStr: "custom-columns format specified but no custom columns given",
|
||||
},
|
||||
{
|
||||
name: "success single object",
|
||||
objects: &v1alpha1.Phase{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "phase"},
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "p1",
|
||||
template: "NAME:metadata.name",
|
||||
expected: "NAME\nphase\n",
|
||||
},
|
||||
{
|
||||
name: "success multiple objects",
|
||||
objects: []*v1alpha1.Phase{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "phase1"},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "phase2"},
|
||||
},
|
||||
},
|
||||
template: "NAME:metadata.name",
|
||||
expected: "NAME\nphase1\nphase2\n",
|
||||
},
|
||||
}
|
||||
expectedOut := [][]byte{
|
||||
[]byte("NAMESPACE RESOURCE "),
|
||||
[]byte(" Phase/p1 "),
|
||||
{},
|
||||
}
|
||||
|
||||
rt, err := util.NewResourceTable(resources, func(util.Printable) *util.PrintResourceStatus { return nil })
|
||||
require.NoError(t, err)
|
||||
buf := &bytes.Buffer{}
|
||||
util.DefaultTablePrinter(buf, nil).PrintTable(rt, 0)
|
||||
out, err := ioutil.ReadAll(buf)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedOut, bytes.Split(out, []byte("\n")))
|
||||
}
|
||||
|
||||
func TestDefaultStatusFunction(t *testing.T) {
|
||||
f := util.DefaultStatusFunction()
|
||||
expectedObj := map[string]interface{}{
|
||||
"kind": "Phase",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "p1",
|
||||
"creationTimestamp": nil,
|
||||
},
|
||||
"config": map[string]interface{}{
|
||||
"documentEntryPoint": "",
|
||||
"executorRef": nil,
|
||||
"validation": map[string]interface{}{},
|
||||
},
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
buf := &bytes.Buffer{}
|
||||
err := util.PrintObjects(tt.objects, tt.template, buf, tt.noHeaders)
|
||||
if tt.errorStr != "" {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), tt.errorStr)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expected, buf.String())
|
||||
}
|
||||
buf.Reset()
|
||||
})
|
||||
}
|
||||
printable := &airapiv1.Phase{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Phase",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "p1",
|
||||
},
|
||||
}
|
||||
rs := f(printable)
|
||||
assert.Equal(t, expectedObj, rs.Resource.Object)
|
||||
}
|
||||
|
||||
func TestNonPrintable(t *testing.T) {
|
||||
_, err := util.NewResourceTable("non Printable string", util.DefaultStatusFunction())
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestPrintTableForSingleResource(t *testing.T) {
|
||||
resource := &airapiv1.Phase{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Phase",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "p1",
|
||||
},
|
||||
}
|
||||
expectedOut := [][]byte{
|
||||
[]byte("NAMESPACE RESOURCE "),
|
||||
[]byte(" Phase/p1 "),
|
||||
{},
|
||||
}
|
||||
rt, err := util.NewResourceTable(resource, func(util.Printable) *util.PrintResourceStatus { return nil })
|
||||
require.NoError(t, err)
|
||||
buf := &bytes.Buffer{}
|
||||
util.DefaultTablePrinter(buf, nil).PrintTable(rt, 0)
|
||||
out, err := ioutil.ReadAll(buf)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedOut, bytes.Split(out, []byte("\n")))
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ package util
|
||||
|
||||
import (
|
||||
"io"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/liggitt/tabwriter"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -24,10 +25,11 @@ const (
|
||||
tabwriterWidth = 4
|
||||
tabwriterPadding = 3
|
||||
tabwriterPadChar = ' '
|
||||
tabwriterFlags = 0
|
||||
tabwriterFlags = tabwriter.RememberWidths
|
||||
)
|
||||
|
||||
// NewTabWriter returns a tabwriter that translates tabbed columns in input into properly aligned text.
|
||||
func NewTabWriter(out io.Writer) *tabwriter.Writer {
|
||||
return tabwriter.NewWriter(out, tabwriterMinWidth, tabwriterWidth, tabwriterPadding, tabwriterPadChar, tabwriterFlags)
|
||||
// GetNewTabWriter returns a tabwriter that translates tabbed columns in input into properly aligned text.
|
||||
func GetNewTabWriter(output io.Writer) *tabwriter.Writer {
|
||||
return tabwriter.NewWriter(output, tabwriterMinWidth, tabwriterWidth, tabwriterPadding,
|
||||
tabwriterPadChar, tabwriterFlags)
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ func TestNewTabWriter(t *testing.T) {
|
||||
tt := tt
|
||||
t.Run(tt.testname, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
out := util.NewTabWriter(&buf)
|
||||
out := util.GetNewTabWriter(&buf)
|
||||
fmt.Fprintln(out, tt.src)
|
||||
err := out.Flush()
|
||||
assert.NoError(t, err)
|
||||
|
@ -15,95 +15,33 @@
|
||||
package k8sutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/cli-utils/pkg/apply/event"
|
||||
applyevent "sigs.k8s.io/cli-utils/pkg/apply/event"
|
||||
clicommon "sigs.k8s.io/cli-utils/pkg/common"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/pkg/events"
|
||||
)
|
||||
|
||||
// SuccessEvents returns list of events that constitute a successful cli utils apply
|
||||
func SuccessEvents() []applyevent.Event {
|
||||
cm := &v1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: document.ConfigMapKind,
|
||||
APIVersion: document.ConfigMapVersion,
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-%s", "airshipit", "inventoryID"),
|
||||
Namespace: "airshipit",
|
||||
Labels: map[string]string{
|
||||
clicommon.InventoryLabel: "inventoryID",
|
||||
},
|
||||
},
|
||||
Data: map[string]string{
|
||||
"test_test-rc__ReplicationController": "",
|
||||
},
|
||||
}
|
||||
return []applyevent.Event{
|
||||
func SuccessEvents() []events.ApplierEvent {
|
||||
return []events.ApplierEvent{
|
||||
{
|
||||
Type: applyevent.InitType,
|
||||
InitEvent: applyevent.InitEvent{
|
||||
ResourceGroups: []applyevent.ResourceGroup{
|
||||
{
|
||||
Action: applyevent.ApplyAction,
|
||||
Identifiers: []object.ObjMetadata{
|
||||
{
|
||||
Namespace: "test",
|
||||
Name: "test-rc",
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "ReplicationController",
|
||||
},
|
||||
},
|
||||
{
|
||||
Namespace: "airshipit",
|
||||
Name: "airshipit-test-bundle-4bf1e4a",
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Action: applyevent.PruneAction,
|
||||
Identifiers: []object.ObjMetadata{},
|
||||
},
|
||||
},
|
||||
},
|
||||
Operation: "init",
|
||||
Message: "success",
|
||||
},
|
||||
{
|
||||
Type: applyevent.ApplyType,
|
||||
ApplyEvent: applyevent.ApplyEvent{
|
||||
Type: applyevent.ApplyEventResourceUpdate,
|
||||
Operation: applyevent.Configured,
|
||||
Object: cm,
|
||||
},
|
||||
Operation: "configured",
|
||||
Message: "success",
|
||||
},
|
||||
{
|
||||
Type: applyevent.ApplyType,
|
||||
ApplyEvent: applyevent.ApplyEvent{
|
||||
Type: applyevent.ApplyEventCompleted,
|
||||
},
|
||||
Operation: "completed",
|
||||
Message: "success",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorEvents return a list of events with error
|
||||
func ErrorEvents() []applyevent.Event {
|
||||
return []applyevent.Event{
|
||||
func ErrorEvents() []events.ApplierEvent {
|
||||
return []events.ApplierEvent{
|
||||
{
|
||||
Type: event.ErrorType,
|
||||
ErrorEvent: event.ErrorEvent{
|
||||
Err: fmt.Errorf("apply-error"),
|
||||
},
|
||||
Operation: "error",
|
||||
Message: "apply-error",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,380 +0,0 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package k8sutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/rest/fake"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
kubeconfig "k8s.io/client-go/tools/clientcmd/api"
|
||||
cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubectl/pkg/validation"
|
||||
)
|
||||
|
||||
// MockKubectlFactory implements Factory interface for testing purposes.
|
||||
type MockKubectlFactory struct {
|
||||
MockToDiscoveryClient func() (discovery.CachedDiscoveryInterface, error)
|
||||
MockDynamicClient func() (dynamic.Interface, error)
|
||||
MockOpenAPISchema func() (openapi.Resources, error)
|
||||
MockValidator func() (validation.Schema, error)
|
||||
MockToRESTMapper func() (meta.RESTMapper, error)
|
||||
MockToRESTConfig func() (*rest.Config, error)
|
||||
MockNewBuilder func() *resource.Builder
|
||||
MockToRawKubeConfigLoader func() clientcmd.ClientConfig
|
||||
MockClientForMapping func() (resource.RESTClient, error)
|
||||
KubeConfig kubeconfig.Config
|
||||
genericclioptions.ConfigFlags
|
||||
cmdutil.Factory
|
||||
}
|
||||
|
||||
// ToDiscoveryClient implements Factory interface
|
||||
func (f *MockKubectlFactory) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
|
||||
return f.MockToDiscoveryClient()
|
||||
}
|
||||
|
||||
// DynamicClient implements Factory interface
|
||||
// Returns a mock dynamic client ready for use
|
||||
func (f *MockKubectlFactory) DynamicClient() (dynamic.Interface, error) { return f.MockDynamicClient() }
|
||||
|
||||
// OpenAPISchema implements Factory interface
|
||||
// Returns a mock openapi schema definition. Schema definition includes metadata and structural information about
|
||||
// Kubernetes object definitions
|
||||
func (f *MockKubectlFactory) OpenAPISchema() (openapi.Resources, error) { return f.MockOpenAPISchema() }
|
||||
|
||||
// Validator implements Factory interface
|
||||
// Returns a mock schema that can validate objects stored on disk
|
||||
func (f *MockKubectlFactory) Validator(bool) (validation.Schema, error) {
|
||||
return f.MockValidator()
|
||||
}
|
||||
|
||||
// ToRESTMapper implements Factory interface
|
||||
// Returns a mock RESTMapper
|
||||
// RESTMapper allows clients to map resources to kind, and map kind and version to interfaces for manipulating
|
||||
// those objects. It is primarily intended for consumers of Kubernetes compatible REST APIs
|
||||
func (f *MockKubectlFactory) ToRESTMapper() (meta.RESTMapper, error) { return f.MockToRESTMapper() }
|
||||
|
||||
// ToRESTConfig implements Factory interface
|
||||
// Returns a mock Config
|
||||
// Config holds the common attributes that can be passed to a Kubernetes client on initialization
|
||||
func (f *MockKubectlFactory) ToRESTConfig() (*rest.Config, error) { return f.MockToRESTConfig() }
|
||||
|
||||
// NewBuilder implements Factory interface
|
||||
// Returns a mock object that assists in loading objects from both disk and the server
|
||||
func (f *MockKubectlFactory) NewBuilder() *resource.Builder { return f.MockNewBuilder() }
|
||||
|
||||
// ToRawKubeConfigLoader implements Factory interface
|
||||
func (f *MockKubectlFactory) ToRawKubeConfigLoader() clientcmd.ClientConfig {
|
||||
return f.MockToRawKubeConfigLoader()
|
||||
}
|
||||
|
||||
// ClientForMapping implements Factory interface
|
||||
// Returns a mock RESTClient for working with the specified RESTMapping or an error
|
||||
func (f *MockKubectlFactory) ClientForMapping(*meta.RESTMapping) (resource.RESTClient, error) {
|
||||
return f.MockClientForMapping()
|
||||
}
|
||||
|
||||
// WithToDiscoveryClientByError returns mock discovery client with its respective error
|
||||
func (f *MockKubectlFactory) WithToDiscoveryClientByError(d discovery.CachedDiscoveryInterface,
|
||||
err error) *MockKubectlFactory {
|
||||
f.MockToDiscoveryClient = func() (discovery.CachedDiscoveryInterface, error) { return d, err }
|
||||
return f
|
||||
}
|
||||
|
||||
// WithOpenAPISchemaByError returns mock openAPISchema with its respective error
|
||||
func (f *MockKubectlFactory) WithOpenAPISchemaByError(r openapi.Resources, err error) *MockKubectlFactory {
|
||||
f.MockOpenAPISchema = func() (openapi.Resources, error) { return r, err }
|
||||
return f
|
||||
}
|
||||
|
||||
// WithDynamicClientByError returns mock dynamic client with its respective error
|
||||
func (f *MockKubectlFactory) WithDynamicClientByError(d dynamic.Interface, err error) *MockKubectlFactory {
|
||||
f.MockDynamicClient = func() (dynamic.Interface, error) { return d, err }
|
||||
return f
|
||||
}
|
||||
|
||||
// WithValidatorByError returns mock validator with its respective error
|
||||
func (f *MockKubectlFactory) WithValidatorByError(v validation.Schema, err error) *MockKubectlFactory {
|
||||
f.MockValidator = func() (validation.Schema, error) { return v, err }
|
||||
return f
|
||||
}
|
||||
|
||||
// WithToRESTMapperByError returns mock RESTMapper with its respective error
|
||||
func (f *MockKubectlFactory) WithToRESTMapperByError(r meta.RESTMapper, err error) *MockKubectlFactory {
|
||||
f.MockToRESTMapper = func() (meta.RESTMapper, error) { return r, err }
|
||||
return f
|
||||
}
|
||||
|
||||
// WithToRESTConfigByError returns mock RESTConfig with its respective error
|
||||
func (f *MockKubectlFactory) WithToRESTConfigByError(r *rest.Config, err error) *MockKubectlFactory {
|
||||
f.MockToRESTConfig = func() (*rest.Config, error) { return r, err }
|
||||
return f
|
||||
}
|
||||
|
||||
// WithNewBuilderByError returns mock resource builder with its respective error
|
||||
func (f *MockKubectlFactory) WithNewBuilderByError(r *resource.Builder) *MockKubectlFactory {
|
||||
f.MockNewBuilder = func() *resource.Builder { return r }
|
||||
return f
|
||||
}
|
||||
|
||||
// WithToRawKubeConfigLoaderByError returns mock raw kubeconfig loader with its respective error
|
||||
func (f *MockKubectlFactory) WithToRawKubeConfigLoaderByError(c clientcmd.ClientConfig) *MockKubectlFactory {
|
||||
f.MockToRawKubeConfigLoader = func() clientcmd.ClientConfig { return c }
|
||||
return f
|
||||
}
|
||||
|
||||
// WithClientForMappingByError returns mock client mapping with its respective error
|
||||
func (f *MockKubectlFactory) WithClientForMappingByError(r resource.RESTClient, err error) *MockKubectlFactory {
|
||||
f.MockClientForMapping = func() (resource.RESTClient, error) { return r, err }
|
||||
return f
|
||||
}
|
||||
|
||||
// NewMockKubectlFactory defines the functions of MockKubectlFactory with nil values for testing purpose
|
||||
func NewMockKubectlFactory() *MockKubectlFactory {
|
||||
return &MockKubectlFactory{MockDynamicClient: func() (dynamic.Interface, error) { return nil, nil },
|
||||
MockToDiscoveryClient: func() (discovery.CachedDiscoveryInterface, error) { return nil, nil },
|
||||
MockOpenAPISchema: func() (openapi.Resources, error) { return nil, nil },
|
||||
MockValidator: func() (validation.Schema, error) { return nil, nil },
|
||||
MockToRESTMapper: func() (meta.RESTMapper, error) { return nil, nil },
|
||||
MockToRESTConfig: func() (*rest.Config, error) { return nil, nil },
|
||||
MockNewBuilder: func() *resource.Builder { return nil },
|
||||
MockToRawKubeConfigLoader: func() clientcmd.ClientConfig { return nil },
|
||||
MockClientForMapping: func() (resource.RESTClient, error) { return nil, nil },
|
||||
}
|
||||
}
|
||||
|
||||
// MockClientConfig implements DirectClientConfig interface
|
||||
// Returns mock client config for testing
|
||||
type MockClientConfig struct {
|
||||
clientcmd.DirectClientConfig
|
||||
MockNamespace func() (string, bool, error)
|
||||
}
|
||||
|
||||
// Namespace returns mock namespace for testing
|
||||
func (c MockClientConfig) Namespace() (string, bool, error) { return c.MockNamespace() }
|
||||
|
||||
// WithNamespace returns mock namespace with its respective error
|
||||
func (c *MockClientConfig) WithNamespace(s string, b bool, err error) *MockClientConfig {
|
||||
c.MockNamespace = func() (string, bool, error) { return s, b, err }
|
||||
return c
|
||||
}
|
||||
|
||||
// NewMockClientConfig returns mock client config for testing
|
||||
func NewMockClientConfig() *MockClientConfig {
|
||||
return &MockClientConfig{
|
||||
MockNamespace: func() (string, bool, error) { return "test", false, nil },
|
||||
}
|
||||
}
|
||||
|
||||
// ClientHandler is an interface that can be injected into FakeFactory
|
||||
// it's purpose to mock http request handling done by the Kubernetes Clients produced by cmdutils.Factory
|
||||
type ClientHandler interface {
|
||||
Handle(t *testing.T, req *http.Request) (*http.Response, bool, error)
|
||||
}
|
||||
|
||||
var (
|
||||
nsNamedPathRegex = regexp.MustCompile(`/api/v1/namespaces/([^/]+)`)
|
||||
nsPath = "/api/v1/namespaces"
|
||||
)
|
||||
|
||||
// NamespaceHandler implements ClientHandler, that is to be used to handle
|
||||
// Http Requests made by clients that are produced by cmdutils.Factory interface
|
||||
type NamespaceHandler struct {
|
||||
}
|
||||
|
||||
var _ ClientHandler = &NamespaceHandler{}
|
||||
|
||||
// Handle implements handler
|
||||
func (h *NamespaceHandler) Handle(_ *testing.T, req *http.Request) (*http.Response, bool, error) {
|
||||
c := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
|
||||
switch match, method := nsNamedPathRegex.FindStringSubmatch(req.URL.Path), req.Method; {
|
||||
case match != nil && method == http.MethodGet:
|
||||
ns := &corev1.Namespace{
|
||||
TypeMeta: v1.TypeMeta{
|
||||
Kind: "Namespace",
|
||||
APIVersion: "v1"},
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
// check that this index exists is performed at case statement match != nil
|
||||
// this means that [0] and [1] exist
|
||||
Name: match[1],
|
||||
}}
|
||||
response := &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Header: cmdtesting.DefaultHeader(),
|
||||
Body: cmdtesting.ObjBody(c, ns)}
|
||||
return response, true, nil
|
||||
|
||||
case req.URL.Path == nsPath && method == http.MethodPost:
|
||||
ns := &corev1.Namespace{
|
||||
TypeMeta: v1.TypeMeta{
|
||||
Kind: "Namespace",
|
||||
APIVersion: "v1"},
|
||||
}
|
||||
response := &http.Response{StatusCode: http.StatusOK,
|
||||
Header: cmdtesting.DefaultHeader(),
|
||||
Body: cmdtesting.ObjBody(c, ns)}
|
||||
return response, true, nil
|
||||
}
|
||||
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// InventoryObjectHandler handles configmap inventory object from cli-utils by mocking
|
||||
// http calls made by clients produced by cmdutils.Factory interface
|
||||
type InventoryObjectHandler struct {
|
||||
inventoryObj *corev1.ConfigMap
|
||||
}
|
||||
|
||||
var _ ClientHandler = &InventoryObjectHandler{}
|
||||
|
||||
var (
|
||||
cmPathRegex = regexp.MustCompile(`^/namespaces/([^/]+)/configmaps$`)
|
||||
resourceNameRegexpString = `^[a-zA-Z]+-[a-z0-9]+$`
|
||||
invObjNameRegex = regexp.MustCompile(resourceNameRegexpString)
|
||||
invObjPathRegex = regexp.MustCompile(`^/namespaces/([^/]+)/configmaps/` + resourceNameRegexpString[:1])
|
||||
codec = scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
|
||||
)
|
||||
|
||||
// Handle implements handler
|
||||
func (i *InventoryObjectHandler) Handle(t *testing.T, req *http.Request) (*http.Response, bool, error) {
|
||||
if req.Method == http.MethodPost && cmPathRegex.Match([]byte(req.URL.Path)) {
|
||||
b, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
cm := corev1.ConfigMap{}
|
||||
err = runtime.DecodeInto(codec, b, &cm)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if invObjNameRegex.Match([]byte(cm.Name)) {
|
||||
i.inventoryObj = &cm
|
||||
bodyRC := ioutil.NopCloser(bytes.NewReader(b))
|
||||
return &http.Response{StatusCode: http.StatusCreated, Header: cmdtesting.DefaultHeader(), Body: bodyRC}, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
if req.Method == http.MethodGet && cmPathRegex.Match([]byte(req.URL.Path)) {
|
||||
cmList := corev1.ConfigMapList{
|
||||
TypeMeta: v1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "List",
|
||||
},
|
||||
Items: []corev1.ConfigMap{},
|
||||
}
|
||||
if i.inventoryObj != nil {
|
||||
cmList.Items = append(cmList.Items, *i.inventoryObj)
|
||||
}
|
||||
bodyRC := ioutil.NopCloser(bytes.NewReader(toJSONBytes(t, &cmList)))
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: bodyRC}, true, nil
|
||||
}
|
||||
|
||||
if req.Method == http.MethodGet && invObjPathRegex.Match([]byte(req.URL.Path)) {
|
||||
if i.inventoryObj == nil {
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusNotFound,
|
||||
Header: cmdtesting.DefaultHeader(),
|
||||
Body: cmdtesting.StringBody("")}, true, nil
|
||||
}
|
||||
bodyRC := ioutil.NopCloser(bytes.NewReader(toJSONBytes(t, i.inventoryObj)))
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: bodyRC}, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// GenericHandler is a handler for generic objects
|
||||
type GenericHandler struct {
|
||||
Obj runtime.Object
|
||||
Namespace string
|
||||
// URLPath is a string for formatter in which it should be defined how to inject a namespace into it
|
||||
// example : /namespaces/%s/deployments
|
||||
URLPath string
|
||||
Bytes []byte
|
||||
}
|
||||
|
||||
var _ ClientHandler = &GenericHandler{}
|
||||
|
||||
// Handle implements handler
|
||||
func (g *GenericHandler) Handle(t *testing.T, req *http.Request) (*http.Response, bool, error) {
|
||||
err := runtime.DecodeInto(codec, g.Bytes, g.Obj)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
accessor, err := meta.Accessor(g.Obj)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
basePath := fmt.Sprintf(g.URLPath, g.Namespace)
|
||||
resourcePath := path.Join(basePath, accessor.GetName())
|
||||
if req.URL.Path == resourcePath && req.Method == http.MethodGet {
|
||||
bodyRC := ioutil.NopCloser(bytes.NewReader(toJSONBytes(t, g.Obj)))
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: bodyRC}, true, nil
|
||||
}
|
||||
if req.URL.Path == resourcePath && req.Method == http.MethodPatch {
|
||||
bodyRC := ioutil.NopCloser(bytes.NewReader(toJSONBytes(t, g.Obj)))
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: bodyRC}, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
func toJSONBytes(t *testing.T, obj runtime.Object) []byte {
|
||||
objBytes, err := runtime.Encode(unstructured.NewJSONFallbackEncoder(codec), obj)
|
||||
require.NoError(t, err)
|
||||
return objBytes
|
||||
}
|
||||
|
||||
// FakeFactory returns a fake factory based on provided handlers
|
||||
func FakeFactory(t *testing.T, handlers []ClientHandler) *cmdtesting.TestFactory {
|
||||
f := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer f.Cleanup()
|
||||
testRESTClient := &fake.RESTClient{
|
||||
NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
|
||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||
for _, h := range handlers {
|
||||
resp, handled, err := h.Handle(t, req)
|
||||
if handled {
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
|
||||
// dummy return
|
||||
return nil, nil
|
||||
}),
|
||||
}
|
||||
f.Client = testRESTClient
|
||||
f.UnstructuredClient = testRESTClient
|
||||
return f
|
||||
}
|
@ -23,7 +23,7 @@ export PROXY=${PROXY:-${http_proxy}}
|
||||
set +e
|
||||
echo "Build airshipctl docker images"
|
||||
for i in {1..3}; do
|
||||
sudo -E make images && break
|
||||
sudo -E make images && break
|
||||
done
|
||||
[ "$?" -ne 0 ] && exit 1
|
||||
set -e
|
||||
|
@ -72,7 +72,7 @@ for site_root in ${SITE_ROOTS}; do
|
||||
|
||||
echo -e "\nValidating site: ${MANIFEST_ROOT}/${site_root}/${site}\n****************"
|
||||
generate_airshipconf $site
|
||||
phase_plans=$(airshipctl --airshipconf "${TMP}/$site.cfg" plan list | awk -F'/' '/PhasePlan/ {print $2}' | awk '{print $1}')
|
||||
phase_plans=$(airshipctl --airshipconf "${TMP}/$site.cfg" plan list | tail -n +2 | awk '{print $1}')
|
||||
for plan in $phase_plans; do
|
||||
airshipctl --airshipconf "${TMP}/$site.cfg" plan validate $plan
|
||||
done
|
||||
|
Loading…
Reference in New Issue
Block a user