diff --git a/go.mod b/go.mod index aeabd35e36..7823737cee 100644 --- a/go.mod +++ b/go.mod @@ -80,6 +80,7 @@ require ( github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.4.2 + github.com/gruntwork-io/terratest v0.40.6 github.com/k3s-io/helm-controller v0.12.0 github.com/k3s-io/kine v0.8.1 github.com/klauspost/compress v1.14.2 diff --git a/go.sum b/go.sum index 923476fe79..46a8a46ab9 100644 --- a/go.sum +++ b/go.sum @@ -45,10 +45,12 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy 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= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= 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= dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE= +github.com/Azure/azure-sdk-for-go v50.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v55.0.0+incompatible h1:L4/vUGbg1Xkw5L20LZD+hJI5I+ibWSytqQ68lTCfLwY= github.com/Azure/azure-sdk-for-go v55.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -57,18 +59,26 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM= +github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.20 h1:s8H1PbCZSqg/DH7JMlOz6YMig6htWLNPsjDdlLqCx3M= +github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.1.0 h1:ISSNzGUh+ZSzizJWOWzs8bwpXIePbGLW4z/AmUFGH5A= github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= +github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= @@ -104,6 +114,9 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Rican7/retry v0.1.0 h1:FqK94z34ly8Baa6K+G8Mmza9rYWTKOJk+yckIBB5qVk= github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -117,6 +130,11 @@ github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9Pq github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e h1:GCzyKMDDjSGnlpl3clrdAK7I1AaVoaiKDOYkUzChZzg= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= 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= @@ -126,11 +144,14 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/auth0/go-jwt-middleware v1.0.1/go.mod h1:YSeUX3z6+TF2H+7padiEqNJ73Zy9vXW72U//IgN0BIM= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.38.70 h1:EGHVUQzHIxQDF9LwQU22yE9bJd1HuBAWpJYSEnxnnhc= github.com/aws/aws-sdk-go v1.38.70/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.40.56 h1:FM2yjR0UUYFzDTMx+mH9Vyw1k1EUUxsAFzk+BjkzANA= +github.com/aws/aws-sdk-go v1.40.56/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -138,6 +159,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= @@ -147,6 +170,7 @@ github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bronze1man/goStrongswanVici v0.0.0-20201105010758-936f38b697fd h1:qn6a8rGrW+7p4ghypmYHZUKewXURuUDYxKqZxEoFjPc= github.com/bronze1man/goStrongswanVici v0.0.0-20201105010758-936f38b697fd/go.mod h1:fWUtBEPt2yjrr3WFhOqvajM8JSEU8bEeBcoeSCsKRpc= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= @@ -165,6 +189,7 @@ github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41 github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/checkpoint-restore/go-criu/v5 v5.0.0 h1:TW8f/UvntYoVDMN1K2HlT82qH1rb0sOjpGw3m6Ym+i4= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= 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= @@ -215,6 +240,7 @@ github.com/containerd/nri v0.1.0 h1:6QioHRlThlKh2RkRTR4kIT3PKAcrLo3gIWnjkM4dQmQ= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/stargz-snapshotter v0.11.0 h1:SDqrMixVWFWya1t/ZcUzfmLY3bLVu0mYnVobN5GOZxw= github.com/containerd/stargz-snapshotter v0.11.0/go.mod h1:4uHVxcpajrdsb7lTjhQ9Aw2iYicB7szTSFu4YqDOpTo= +github.com/containerd/stargz-snapshotter/estargz v0.7.0/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw= github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= github.com/containerd/stargz-snapshotter/estargz v0.11.0 h1:t0IW5kOmY7AXDAWRUs2uVzDhijAUOAYVr/dyRhOQvBg= github.com/containerd/stargz-snapshotter/estargz v0.11.0/go.mod h1:/KsZXsJRllMbTKFfG0miFQWViQKdI9+9aSXs+HN0+ac= @@ -276,8 +302,11 @@ github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8l github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20171119141306-ac7624ea8da3/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.12+incompatible h1:lZlz0uzG+GH+c0plStMUdF/qk3ppmgnswpR5EbqzVGA= github.com/docker/cli v20.10.12+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -285,6 +314,7 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -296,6 +326,7 @@ github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHz github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= 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 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= @@ -303,8 +334,10 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk= github.com/eapache/channels v1.1.0/go.mod h1:jMm2qB5Ubtg9zLd+inMZd2/NUvXgzmWXsDaLyQIGfH0= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 h1:yY9rWGoXv1U5pl4gxqlULARMQD7x0QG85lqEXTWysik= +github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -353,8 +386,9 @@ github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE= github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= -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-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU= +github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/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= @@ -420,11 +454,15 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ 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-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 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/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.6/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= +github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= +github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c h1:RBUpb2b14UnmRHNd2uHz20ZHLDK+SW5Us/vWF5IHRaY= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -489,14 +527,17 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw= github.com/google/go-containerregistry v0.6.1-0.20211111182346-7a6ee45528a9 h1:m5Yu3eJF1gVvzA51M9Ll2TZH+fi8P38bBVDL2jdQzoU= github.com/google/go-containerregistry v0.6.1-0.20211111182346-7a6ee45528a9/go.mod h1:VGc0QpDDhK6zwYGlQb3s0LDGbTCGMFiifm0UgG9v1oQ= 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 h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= 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= @@ -554,38 +595,55 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= +github.com/gruntwork-io/terratest v0.40.6 h1:kBYzD9gcQoruAoV9vmVLk8kjuZAUI5U72h9IAogL/iI= +github.com/gruntwork-io/terratest v0.40.6/go.mod h1:CjHsEgP1Pe987X5N8K5qEqCuLtu1bqERGIAF8bTj1s0= github.com/hanwen/go-fuse/v2 v2.1.1-0.20220112183258-f57e95bda82d h1:ibbzF2InxMOS+lLCphY9PHNKPURDUBNKaG6ErSq8gJQ= github.com/hanwen/go-fuse/v2 v2.1.1-0.20220112183258-f57e95bda82d/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.5.9 h1:b7ahZW50iQiUek/at3CvZhPK1/jiV6CtKcsJiR6E4R0= +github.com/hashicorp/go-getter v1.5.9/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= 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-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4= github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= 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.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= +github.com/hashicorp/go-version v1.3.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.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v0.0.0-20170509225359-392dba7d905e/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl/v2 v2.9.1 h1:eOy4gREY0/ZQHNItlfuEZqtcQbXIxzojlP301hDpnac= +github.com/hashicorp/hcl/v2 v2.9.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= 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/hashicorp/terraform-json v0.13.0 h1:Li9L+lKD1FO5RVFRM1mMMIBDoUHslOniyEi5CM+FWGY= +github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk= github.com/heketi/heketi v10.3.0+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o= github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -594,6 +652,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/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.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 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= @@ -602,6 +661,8 @@ github.com/insomniacslk/dhcp v0.0.0-20210120172423-cc9239ac6294/go.mod h1:TKl4jN github.com/ishidawataru/sctp v0.0.0-20190723014705-7c296d48a2b5/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jessevdk/go-flags v1.3.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= +github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -719,6 +780,9 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.14.2 h1:S0OHlFk/Gbon/yauFJ4FfJJF5V0fc5HbBTJazi28pRw= github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -739,8 +803,9 @@ 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/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libopenstorage/openstorage v1.0.0 h1:GLPam7/0mpdP8ZZtKjbfcXJBTIA/T1O6CBErVEFEyIM= @@ -774,6 +839,9 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= +github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 h1:ofNAzWCcyTALn2Zv40+8XitdzCgXY6e9qvXwN9W0YXg= +github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= 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 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -799,6 +867,7 @@ github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/ github.com/mdlayher/socket v0.0.0-20211007213009-516dcbdf0267/go.mod h1:nFZ1EtZYK8Gi/k6QNu7z7CgO20i/4ExeQswwWuPmG/g= github.com/mdlayher/socket v0.0.0-20211102153432-57e3fa563ecb/go.mod h1:nFZ1EtZYK8Gi/k6QNu7z7CgO20i/4ExeQswwWuPmG/g= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= @@ -814,12 +883,16 @@ github.com/minio/sio v0.2.1/go.mod h1:8b0yPp2avGThviy/+OCJBI6OMpvxoUuiLvE6F1lebh github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= 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 v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= 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= @@ -827,6 +900,7 @@ github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/ipvs v1.0.1 h1:aoZ7fhLTXgDbzVrAnvV+XbKOU8kOET7B3+xULDF/1o0= github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= @@ -914,6 +988,7 @@ github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xA github.com/opencontainers/selinux v1.8.3 h1:tzZR7AuKB5gU1+53uBkoG4XdIFGZzvJTOVoNbRQI8/4= github.com/opencontainers/selinux v1.8.3/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/osrg/gobgp v0.0.0-20210801043420-9e48a36ed97c/go.mod h1:aNi0T2X6FSkl1evOifmJUsdxiQ1AQkiV7fIEtLIVv/U= github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= @@ -946,6 +1021,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021 h1:0XM1XL/OFFJjXsYXlG30spTkV/E9+gmd5GD1w2HE8xM= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -998,6 +1074,7 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rootless-containers/rootlesskit v0.14.5 h1:X4eNt2e1h/uSjlssKqpeTY5fatrjDz9F9FX05RJB7Tw= github.com/rootless-containers/rootlesskit v0.14.5/go.mod h1:Ai3detLzryb/4EkzXmNfh8aByUcBXp/qqkQusJs1SO8= @@ -1016,6 +1093,7 @@ github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8 h1:2c1EFnZHIPCW8q github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -1064,6 +1142,7 @@ github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzu github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/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= @@ -1101,9 +1180,13 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ= +github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/u-root/u-root v7.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -1125,6 +1208,9 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmware/govmomi v0.20.3 h1:gpw/0Ku+6RgF3jsi7fnCLmlcikBHfKBCUcu1qgc16OU= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= @@ -1139,6 +1225,12 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty v1.8.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty v1.9.1 h1:viqrgQwFl5UpSxc046qblj78wZXVDFnSOufaOTER+cc= +github.com/zclconf/go-cty v1.9.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= 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.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= @@ -1313,6 +1405,7 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb 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-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1346,6 +1439,7 @@ golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtn 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-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 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-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1435,6 +1529,7 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6 google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0 h1:4t9zuDlHLcIx0ZEhmXEeFVCRsiOgpgn2QOH9N0MNjPI= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1462,6 +1557,7 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.27/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.0 h1:0HIbH907iBTAntm+88IJV2qmJALDAh8sPekI9Vc1fm0= diff --git a/tests/terraform/Dockerfile.build b/tests/terraform/Dockerfile.build new file mode 100644 index 0000000000..7457827774 --- /dev/null +++ b/tests/terraform/Dockerfile.build @@ -0,0 +1,26 @@ +FROM golang:alpine + +ARG TERRAFORM_VERSION=0.12.10 +ENV TERRAFORM_VERSION=$TERRAFORM_VERSION + + +RUN apk update && \ + apk upgrade --update-cache --available && \ + apk add curl git jq bash openssh unzip gcc g++ make ca-certificates && \ + +RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ + chmod +x ./kubectl && \ + mv ./kubectl /usr/local/bin +RUN mkdir tmp && \ + curl "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip" -o tmp/terraform.zip && \ + unzip tmp/terraform.zip -d /usr/local/bin && \ + chmod +x /usr/local/bin/terraform && \ + rm -rf tmp + +WORKDIR $GOPATH/src/github.com/k3s-io/k3s + +COPY . . +RUN go get github.com/gruntwork-io/terratest/modules/terraform +RUN go get -u github.com/onsi/gomega +RUN go get -u github.com/onsi/ginkgo/v2 +RUN go get -u golang.org/x/crypto/... diff --git a/tests/terraform/amd64_resource_files/clusterip.yaml b/tests/terraform/amd64_resource_files/clusterip.yaml new file mode 100644 index 0000000000..f1c501e8fa --- /dev/null +++ b/tests/terraform/amd64_resource_files/clusterip.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-clusterip +spec: + selector: + matchLabels: + k8s-app: nginx-app-clusterip + replicas: 2 + template: + metadata: + labels: + k8s-app: nginx-app-clusterip + spec: + containers: + - name: nginx + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: nginx-app-clusterip + name: nginx-clusterip-svc + namespace: default +spec: + type: ClusterIP + ports: + - port: 80 + selector: + k8s-app: nginx-app-clusterip diff --git a/tests/terraform/amd64_resource_files/daemonset.yaml b/tests/terraform/amd64_resource_files/daemonset.yaml new file mode 100644 index 0000000000..3360f35421 --- /dev/null +++ b/tests/terraform/amd64_resource_files/daemonset.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: test-daemonset +spec: + selector: + matchLabels: + k8s-app: test-daemonset + template: + metadata: + labels: + k8s-app: test-daemonset + spec: + containers: + - name: webserver + image: nginx + ports: + - containerPort: 80 diff --git a/tests/terraform/amd64_resource_files/dnsutils.yaml b/tests/terraform/amd64_resource_files/dnsutils.yaml new file mode 100644 index 0000000000..9192bf3502 --- /dev/null +++ b/tests/terraform/amd64_resource_files/dnsutils.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dnsutils + namespace: default +spec: + containers: + - name: dnsutils + image: gcr.io/kubernetes-e2e-test-images/dnsutils:1.3 + command: + - sleep + - "3600" + imagePullPolicy: IfNotPresent + restartPolicy: Always diff --git a/tests/terraform/amd64_resource_files/ingress.yaml b/tests/terraform/amd64_resource_files/ingress.yaml new file mode 100644 index 0000000000..cf49a50640 --- /dev/null +++ b/tests/terraform/amd64_resource_files/ingress.yaml @@ -0,0 +1,51 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: test-ingress +spec: + rules: + - host: foo1.bar.com + http: + paths: + - backend: + service: + name: nginx-ingress-svc + port: + number: 80 + path: / + pathType: ImplementationSpecific +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-ingress-svc + labels: + k8s-app: nginx-app-ingress +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + k8s-app: nginx-app-ingress +--- +apiVersion: v1 +kind: ReplicationController +metadata: + name: test-ingress +spec: + replicas: 2 + selector: + k8s-app: nginx-app-ingress + template: + metadata: + labels: + k8s-app: nginx-app-ingress + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: testcontainer + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 diff --git a/tests/terraform/amd64_resource_files/loadbalancer.yaml b/tests/terraform/amd64_resource_files/loadbalancer.yaml new file mode 100644 index 0000000000..0897d215ae --- /dev/null +++ b/tests/terraform/amd64_resource_files/loadbalancer.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-loadbalancer +spec: + selector: + matchLabels: + k8s-app: nginx-app-loadbalancer + replicas: 2 + template: + metadata: + labels: + k8s-app: nginx-app-loadbalancer + spec: + containers: + - name: nginx + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-loadbalancer-svc + labels: + k8s-app: nginx-app-loadbalancer +spec: + type: LoadBalancer + ports: + - port: 81 + targetPort: 80 + protocol: TCP + name: http + selector: + k8s-app: nginx-app-loadbalancer diff --git a/tests/terraform/amd64_resource_files/local-path-provisioner.yaml b/tests/terraform/amd64_resource_files/local-path-provisioner.yaml new file mode 100644 index 0000000000..8e2b01ab8f --- /dev/null +++ b/tests/terraform/amd64_resource_files/local-path-provisioner.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: local-path-pvc + namespace: default +spec: + accessModes: + - ReadWriteOnce + storageClassName: local-path + resources: + requests: + storage: 500Mi +--- +apiVersion: v1 +kind: Pod +metadata: + name: volume-test + namespace: default +spec: + containers: + - name: volume-test + image: nginx:stable-alpine + imagePullPolicy: IfNotPresent + volumeMounts: + - name: volv + mountPath: /data + ports: + - containerPort: 80 + volumes: + - name: volv + persistentVolumeClaim: + claimName: local-path-pvc diff --git a/tests/terraform/amd64_resource_files/nodeport.yaml b/tests/terraform/amd64_resource_files/nodeport.yaml new file mode 100644 index 0000000000..2187b732db --- /dev/null +++ b/tests/terraform/amd64_resource_files/nodeport.yaml @@ -0,0 +1,35 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-nodeport +spec: + selector: + matchLabels: + k8s-app: nginx-app-nodeport + replicas: 2 + template: + metadata: + labels: + k8s-app: nginx-app-nodeport + spec: + containers: + - name: nginx + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: nginx-app-nodeport + name: nginx-nodeport-svc + namespace: default +spec: + type: NodePort + ports: + - port: 80 + nodePort: 30096 + name: http + selector: + k8s-app: nginx-app-nodeport diff --git a/tests/terraform/amd64_resource_files/secrets.yaml b/tests/terraform/amd64_resource_files/secrets.yaml new file mode 100644 index 0000000000..9dcd6d5e6d --- /dev/null +++ b/tests/terraform/amd64_resource_files/secrets.yaml @@ -0,0 +1,49 @@ +apiVersion: v1 +kind: Secret +metadata: + name: e2e-secret1 +type: Opaque +stringData: + config.yaml: | + key: "hello" + val: "world" +--- +apiVersion: v1 +kind: Secret +metadata: + name: e2e-secret2 +type: Opaque +stringData: + config.yaml: | + key: "good" + val: "day" +--- +apiVersion: v1 +kind: Secret +metadata: + name: e2e-secret3 +type: Opaque +stringData: + config.yaml: | + key: "top-secret" + val: "information" +--- +apiVersion: v1 +kind: Secret +metadata: + name: e2e-secret4 +type: Opaque +stringData: + config.yaml: | + key: "lock" + val: "key" +--- +apiVersion: v1 +kind: Secret +metadata: + name: e2e-secret5 +type: Opaque +stringData: + config.yaml: | + key: "last" + val: "call" diff --git a/tests/terraform/arm_resource_files/clusterip.yaml b/tests/terraform/arm_resource_files/clusterip.yaml new file mode 100644 index 0000000000..ae5efe6a1e --- /dev/null +++ b/tests/terraform/arm_resource_files/clusterip.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-clusterip +spec: + selector: + matchLabels: + k8s-app: nginx-app-clusterip + replicas: 2 + template: + metadata: + labels: + k8s-app: nginx-app-clusterip + spec: + containers: + - name: nginx + image: shylajarancher19/shylajaarm64:v1.0 + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: nginx-app-clusterip + name: nginx-clusterip-svc + namespace: default +spec: + type: ClusterIP + ports: + - port: 80 + selector: + k8s-app: nginx-app-clusterip diff --git a/tests/terraform/arm_resource_files/daemonset.yaml b/tests/terraform/arm_resource_files/daemonset.yaml new file mode 100644 index 0000000000..3360f35421 --- /dev/null +++ b/tests/terraform/arm_resource_files/daemonset.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: test-daemonset +spec: + selector: + matchLabels: + k8s-app: test-daemonset + template: + metadata: + labels: + k8s-app: test-daemonset + spec: + containers: + - name: webserver + image: nginx + ports: + - containerPort: 80 diff --git a/tests/terraform/arm_resource_files/ingress.yaml b/tests/terraform/arm_resource_files/ingress.yaml new file mode 100644 index 0000000000..67adff28e9 --- /dev/null +++ b/tests/terraform/arm_resource_files/ingress.yaml @@ -0,0 +1,48 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: ingress +spec: + rules: + - host: foo1.bar.com + http: + paths: + - path: /name.html + backend: + serviceName: nginx-ingress-svc + servicePort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-ingress-svc + labels: + k8s-app: nginx-app-ingress +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + k8s-app: nginx-app-ingress +--- +apiVersion: v1 +kind: ReplicationController +metadata: + name: test-ingress +spec: + replicas: 2 + selector: + k8s-app: nginx-app-ingress + template: + metadata: + labels: + k8s-app: nginx-app-ingress + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: testcontainer + image: shylajarancher19/shylajaarm64:v1.0 + ports: + - containerPort: 80 diff --git a/tests/terraform/arm_resource_files/loadbalancer.yaml b/tests/terraform/arm_resource_files/loadbalancer.yaml new file mode 100644 index 0000000000..6cc02bd898 --- /dev/null +++ b/tests/terraform/arm_resource_files/loadbalancer.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-loadbalancer +spec: + selector: + matchLabels: + k8s-app: nginx-app-loadbalancer + replicas: 2 + template: + metadata: + labels: + k8s-app: nginx-app-loadbalancer + spec: + containers: + - name: nginx + image: shylajarancher19/shylajaarm64:v1.0 + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-loadbalancer-svc + labels: + k8s-app: nginx-app-loadbalancer +spec: + type: LoadBalancer + ports: + - port: 81 + targetPort: 80 + protocol: TCP + name: http + selector: + k8s-app: nginx-app-loadbalancer diff --git a/tests/terraform/arm_resource_files/local-path-provisioner.yaml b/tests/terraform/arm_resource_files/local-path-provisioner.yaml new file mode 100644 index 0000000000..8e2b01ab8f --- /dev/null +++ b/tests/terraform/arm_resource_files/local-path-provisioner.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: local-path-pvc + namespace: default +spec: + accessModes: + - ReadWriteOnce + storageClassName: local-path + resources: + requests: + storage: 500Mi +--- +apiVersion: v1 +kind: Pod +metadata: + name: volume-test + namespace: default +spec: + containers: + - name: volume-test + image: nginx:stable-alpine + imagePullPolicy: IfNotPresent + volumeMounts: + - name: volv + mountPath: /data + ports: + - containerPort: 80 + volumes: + - name: volv + persistentVolumeClaim: + claimName: local-path-pvc diff --git a/tests/terraform/arm_resource_files/nodeport.yaml b/tests/terraform/arm_resource_files/nodeport.yaml new file mode 100644 index 0000000000..8978efaebb --- /dev/null +++ b/tests/terraform/arm_resource_files/nodeport.yaml @@ -0,0 +1,35 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-nodeport +spec: + selector: + matchLabels: + k8s-app: nginx-app-nodeport + replicas: 2 + template: + metadata: + labels: + k8s-app: nginx-app-nodeport + spec: + containers: + - name: nginx + image: shylajarancher19/shylajaarm64:v1.0 + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: nginx-app-nodeport + name: nginx-nodeport-svc + namespace: default +spec: + type: NodePort + ports: + - port: 80 + nodePort: 30096 + name: http + selector: + k8s-app: nginx-app-nodeport diff --git a/tests/terraform/createcluster.go b/tests/terraform/createcluster.go new file mode 100644 index 0000000000..920206facd --- /dev/null +++ b/tests/terraform/createcluster.go @@ -0,0 +1,67 @@ +package e2e + +import ( + "flag" + "fmt" + "path/filepath" + "testing" + + "github.com/gruntwork-io/terratest/modules/terraform" +) + +var destroy = flag.Bool("destroy", false, "a bool") +var nodeOs = flag.String("node_os", "centos8", "a string") +var externalDb = flag.String("external_db", "mysql", "a string") +var arch = flag.String("arch", "amd64", "a string") +var clusterType = flag.String("cluster_type", "etcd", "a string") +var resourceName = flag.String("resource_name", "etcd", "a string") +var sshuser = flag.String("sshuser", "ubuntu", "a string") +var sshkey = flag.String("sshkey", "", "a string") + +var ( + kubeConfigFile string + masterIPs string + workerIPs string +) + +func BuildCluster(nodeOs, clusterType, externalDb, resourceName string, t *testing.T, destroy bool) (string, string, string, error) { + + tDir := "./modules/k3scluster" + vDir := "/config/" + nodeOs + clusterType + ".tfvars" + + if externalDb != "" { + vDir = "/config/" + nodeOs + externalDb + ".tfvars" + } + + tfDir, _ := filepath.Abs(tDir) + if err != nil { + return "", "", "", err + } + varDir, _ := filepath.Abs(vDir) + if err != nil { + return "", "", "", err + } + TerraformOptions := &terraform.Options{ + TerraformDir: tfDir, + VarFiles: []string{varDir}, + Vars: map[string]interface{}{ + "cluster_type": clusterType, + "resource_name": resourceName, + "external_db": externalDb, + }, + } + + if destroy { + fmt.Printf("Cluster is being deleted") + terraform.Destroy(t, TerraformOptions) + return "", "", "", err + } + + fmt.Printf("Creating Cluster") + terraform.InitAndApply(t, TerraformOptions) + kubeconfig := terraform.Output(t, TerraformOptions, "kubeconfig") + "_kubeconfig" + masterIPs := terraform.Output(t, TerraformOptions, "master_ips") + workerIPs := terraform.Output(t, TerraformOptions, "worker_ips") + kubeconfigFile := "/config/" + kubeconfig + return kubeconfigFile, masterIPs, workerIPs, err +} diff --git a/tests/terraform/createcluster_test.go b/tests/terraform/createcluster_test.go new file mode 100644 index 0000000000..10232e29a5 --- /dev/null +++ b/tests/terraform/createcluster_test.go @@ -0,0 +1,320 @@ +package e2e + +import ( + "flag" + "fmt" + "strings" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func Test_E2EClusterCreateValidation(t *testing.T) { + RegisterFailHandler(Fail) + flag.Parse() + RunSpecs(t, "Create Cluster Test Suite") +} + +var _ = Describe("Test:", func() { + Context("Build Cluster:", func() { + It("Starts up with no issues", func() { + kubeConfigFile, masterIPs, workerIPs, err = BuildCluster(*nodeOs, *clusterType, *externalDb, *resourceName, &testing.T{}, *destroy) + Expect(err).NotTo(HaveOccurred()) + defer GinkgoRecover() + if *destroy { + fmt.Printf("\nCluster is being Deleted\n") + return + } + fmt.Println("\nCLUSTER CONFIG:\nOS", *nodeOs, "BACKEND", *clusterType, *externalDb) + fmt.Printf("\nIPs:\n") + fmt.Println("Server Node IPS:", masterIPs) + fmt.Println("Agent Node IPS:", workerIPs) + fmt.Println(kubeConfigFile) + Expect(kubeConfigFile).Should(ContainSubstring(*resourceName)) + }) + + It("Checks Node and Pod Status", func() { + fmt.Printf("\nFetching node status\n") + Eventually(func(g Gomega) { + nodes, err := ParseNodes(kubeConfigFile, false) + g.Expect(err).NotTo(HaveOccurred()) + for _, node := range nodes { + g.Expect(node.Status).Should(Equal("Ready")) + } + }, "420s", "5s").Should(Succeed()) + _, _ = ParseNodes(kubeConfigFile, true) + + fmt.Printf("\nFetching Pods status\n") + Eventually(func(g Gomega) { + pods, err := ParsePods(kubeConfigFile, false) + g.Expect(err).NotTo(HaveOccurred()) + for _, pod := range pods { + if strings.Contains(pod.Name, "helm-install") { + g.Expect(pod.Status).Should(Equal("Completed"), pod.Name) + } else { + g.Expect(pod.Status).Should(Equal("Running"), pod.Name) + } + } + }, "420s", "5s").Should(Succeed()) + _, _ = ParsePods(kubeConfigFile, true) + }) + + It("Verifies ClusterIP Service", func() { + _, err := DeployWorkload("clusterip.yaml", kubeConfigFile, false) + Expect(err).NotTo(HaveOccurred(), "Cluster IP manifest not deployed") + + Eventually(func(g Gomega) { + cmd := "kubectl get pods -o=name -l k8s-app=nginx-app-clusterip --field-selector=status.phase=Running --kubeconfig=" + kubeConfigFile + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(res).Should((ContainSubstring("test-clusterip"))) + }, "420s", "5s").Should(Succeed()) + + clusterip, _ := FetchClusterIP(kubeConfigFile, "nginx-clusterip-svc") + cmd := "curl -L --insecure http://" + clusterip + "/name.html" + fmt.Println(cmd) + nodeExternalIP := FetchNodeExternalIP(kubeConfigFile) + for _, ip := range nodeExternalIP { + Eventually(func(g Gomega) { + res, err := RunCmdOnNode(cmd, ip, *sshuser, *sshkey) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(res).Should(ContainSubstring("test-clusterip")) + + }, "420s", "10s").Should(Succeed()) + } + }) + + It("Verifies NodePort Service", func() { + _, err := DeployWorkload("nodeport.yaml", kubeConfigFile, false) + Expect(err).NotTo(HaveOccurred(), "NodePort manifest not deployed") + nodeExternalIP := FetchNodeExternalIP(kubeConfigFile) + cmd := "kubectl get service nginx-nodeport-svc --kubeconfig=" + kubeConfigFile + " --output jsonpath=\"{.spec.ports[0].nodePort}\"" + nodeport, err := RunCommand(cmd) + Expect(err).NotTo(HaveOccurred()) + + for _, ip := range nodeExternalIP { + Eventually(func(g Gomega) { + cmd := "kubectl get pods -o=name -l k8s-app=nginx-app-nodeport --field-selector=status.phase=Running --kubeconfig=" + kubeConfigFile + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(res).Should(ContainSubstring("test-nodeport")) + }, "240s", "5s").Should(Succeed()) + + cmd = "curl -L --insecure http://" + ip + ":" + nodeport + "/name.html" + fmt.Println(cmd) + Eventually(func(g Gomega) { + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + fmt.Println(res) + g.Expect(res).Should(ContainSubstring("test-nodeport")) + }, "240s", "5s").Should(Succeed()) + } + }) + + It("Verifies LoadBalancer Service", func() { + _, err := DeployWorkload("loadbalancer.yaml", kubeConfigFile, false) + Expect(err).NotTo(HaveOccurred(), "Loadbalancer manifest not deployed") + nodeExternalIP := FetchNodeExternalIP(kubeConfigFile) + cmd := "kubectl get service nginx-loadbalancer-svc --kubeconfig=" + kubeConfigFile + " --output jsonpath=\"{.spec.ports[0].port}\"" + port, err := RunCommand(cmd) + Expect(err).NotTo(HaveOccurred()) + for _, ip := range nodeExternalIP { + + Eventually(func(g Gomega) { + cmd := "kubectl get pods -o=name -l k8s-app=nginx-app-loadbalancer --field-selector=status.phase=Running --kubeconfig=" + kubeConfigFile + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(res).Should(ContainSubstring("test-loadbalancer")) + }, "240s", "5s").Should(Succeed()) + + Eventually(func(g Gomega) { + cmd = "curl -L --insecure http://" + ip + ":" + port + "/name.html" + fmt.Println(cmd) + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + fmt.Println(res) + g.Expect(res).Should(ContainSubstring("test-loadbalancer")) + }, "240s", "5s").Should(Succeed()) + } + }) + + It("Verifies Ingress", func() { + _, err := DeployWorkload("ingress.yaml", kubeConfigFile, false) + Expect(err).NotTo(HaveOccurred(), "Ingress manifest not deployed") + + Eventually(func(g Gomega) { + cmd := "kubectl get pods -o=name -l k8s-app=nginx-app-ingress --field-selector=status.phase=Running --kubeconfig=" + kubeConfigFile + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(res).Should(ContainSubstring("test-ingress")) + }, "240s", "5s").Should(Succeed()) + + ingressIps, err := FetchIngressIP(kubeConfigFile) + Expect(err).NotTo(HaveOccurred(), "Ingress ip is not returned") + + for _, ip := range ingressIps { + cmd := "curl --header host:foo1.bar.com" + " http://" + ip + "/name.html" + fmt.Println(cmd) + + Eventually(func(g Gomega) { + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(res).Should(ContainSubstring("test-ingress")) + }, "240s", "5s").Should(Succeed()) + } + }) + + It("Verifies Daemonset", func() { + _, err := DeployWorkload("daemonset.yaml", kubeConfigFile, false) + Expect(err).NotTo(HaveOccurred(), "Daemonset manifest not deployed") + + nodes, _ := ParseNodes(kubeConfigFile, false) + pods, _ := ParsePods(kubeConfigFile, false) + + Eventually(func(g Gomega) { + count := CountOfStringInSlice("test-daemonset", pods) + fmt.Println("POD COUNT") + fmt.Println(count) + fmt.Println("NODE COUNT") + fmt.Println(len(nodes)) + g.Expect(len(nodes)).Should((Equal(count)), "Daemonset pod count does not match node count") + }, "420s", "10s").Should(Succeed()) + }) + + It("Verifies Local Path Provisioner storage ", func() { + _, err := DeployWorkload("local-path-provisioner.yaml", kubeConfigFile, false) + Expect(err).NotTo(HaveOccurred(), "local-path-provisioner manifest not deployed") + + Eventually(func(g Gomega) { + cmd := "kubectl get pvc local-path-pvc --kubeconfig=" + kubeConfigFile + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + fmt.Println(res) + g.Expect(res).Should(ContainSubstring("local-path-pvc")) + g.Expect(res).Should(ContainSubstring("Bound")) + }, "420s", "2s").Should(Succeed()) + + Eventually(func(g Gomega) { + cmd := "kubectl get pod volume-test --kubeconfig=" + kubeConfigFile + res, err := RunCommand(cmd) + Expect(err).NotTo(HaveOccurred()) + fmt.Println(res) + g.Expect(res).Should(ContainSubstring("volume-test")) + g.Expect(res).Should(ContainSubstring("Running")) + }, "420s", "2s").Should(Succeed()) + + cmd := "kubectl --kubeconfig=" + kubeConfigFile + " exec volume-test -- sh -c 'echo local-path-test > /data/test'" + _, err = RunCommand(cmd) + Expect(err).NotTo(HaveOccurred()) + fmt.Println("Data stored in pvc: local-path-test") + + cmd = "kubectl delete pod volume-test --kubeconfig=" + kubeConfigFile + res, err := RunCommand(cmd) + Expect(err).NotTo(HaveOccurred()) + fmt.Println(res) + + _, err = DeployWorkload("local-path-provisioner.yaml", kubeConfigFile, false) + Expect(err).NotTo(HaveOccurred(), "local-path-provisioner manifest not deployed") + + Eventually(func(g Gomega) { + cmd := "kubectl get pods -o=name -l app=local-path-provisioner --field-selector=status.phase=Running -n kube-system --kubeconfig=" + kubeConfigFile + res, _ := RunCommand(cmd) + fmt.Println(res) + g.Expect(res).Should(ContainSubstring("pod/local-path-provisioner")) + }, "420s", "2s").Should(Succeed()) + + Eventually(func(g Gomega) { + cmd := "kubectl get pod volume-test --kubeconfig=" + kubeConfigFile + res, err := RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + fmt.Println(res) + g.Expect(res).Should(ContainSubstring("volume-test")) + g.Expect(res).Should(ContainSubstring("Running")) + }, "420s", "2s").Should(Succeed()) + + Eventually(func(g Gomega) { + cmd = "kubectl exec volume-test cat /data/test --kubeconfig=" + kubeConfigFile + res, err = RunCommand(cmd) + g.Expect(err).NotTo(HaveOccurred()) + fmt.Println("Data after re-creation", res) + g.Expect(res).Should(ContainSubstring("local-path-test")) + }, "180s", "2s").Should(Succeed()) + }) + + It("Verifies dns access", func() { + _, err := DeployWorkload("dnsutils.yaml", kubeConfigFile, false) + Expect(err).NotTo(HaveOccurred(), "dnsutils manifest not deployed") + + Eventually(func(g Gomega) { + cmd := "kubectl get pods dnsutils --kubeconfig=" + kubeConfigFile + res, _ := RunCommand(cmd) + fmt.Println(res) + g.Expect(res).Should(ContainSubstring("dnsutils")) + g.Expect(res).Should(ContainSubstring("Running")) + }, "420s", "2s").Should(Succeed()) + + Eventually(func(g Gomega) { + cmd := "kubectl --kubeconfig=" + kubeConfigFile + " exec -t dnsutils -- nslookup kubernetes.default" + res, _ := RunCommand(cmd) + fmt.Println(res) + g.Expect(res).Should(ContainSubstring("kubernetes.default.svc.cluster.local")) + + }, "420s", "2s").Should(Succeed()) + }) + + It("Validate Rebooting nodes", func() { + if *destroy { + return + } + defer GinkgoRecover() + nodeExternalIP := FetchNodeExternalIP(kubeConfigFile) + for _, ip := range nodeExternalIP { + fmt.Println("\nRebooting node: ", ip) + cmd := "ssh -i " + *sshkey + " -o \"StrictHostKeyChecking no\" " + *sshuser + "@" + ip + " sudo reboot" + _, _ = RunCommand(cmd) + time.Sleep(3 * time.Minute) + fmt.Println("\nNode and Pod Status after rebooting node: ", ip) + + Eventually(func(g Gomega) { + nodes, err := ParseNodes(kubeConfigFile, false) + g.Expect(err).NotTo(HaveOccurred()) + for _, node := range nodes { + g.Expect(node.Status).Should(Equal("Ready")) + } + }, "420s", "5s").Should(Succeed()) + _, _ = ParseNodes(kubeConfigFile, true) + + Eventually(func(g Gomega) { + pods, err := ParsePods(kubeConfigFile, false) + g.Expect(err).NotTo(HaveOccurred()) + for _, pod := range pods { + if strings.Contains(pod.Name, "helm-install") { + g.Expect(pod.Status).Should(Equal("Completed"), pod.Name) + } else { + g.Expect(pod.Status).Should(Equal("Running"), pod.Name) + } + } + }, "420s", "5s").Should(Succeed()) + _, _ = ParsePods(kubeConfigFile, true) + } + }) + }) +}) + +var failed = false +var _ = AfterEach(func() { + failed = failed || CurrentGinkgoTestDescription().Failed +}) + +var _ = AfterSuite(func() { + if failed { + fmt.Println("FAILED!") + } else { + kubeConfigFile, masterIPs, workerIPs, err = BuildCluster(*nodeOs, *clusterType, *externalDb, *resourceName, &testing.T{}, true) + if err != nil { + fmt.Println("Error Destroying Cluster", err) + } + } +}) diff --git a/tests/terraform/jenkinsfile b/tests/terraform/jenkinsfile new file mode 100644 index 0000000000..f5d8327563 --- /dev/null +++ b/tests/terraform/jenkinsfile @@ -0,0 +1,99 @@ +pipeline { + agent any + environment { + setupResultsOut = "setup-results.xml" + testResultsOut = "results.xml" + + AWS_ACCESS_KEY_ID = credentials('AWS_ACCESS_KEY_ID') + AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY') + AWS_SSH_PEM_KEY = credentials('AWS_SSH_PEM_KEY') + } + + stages { + stage('Git Checkout') { + steps { + git branch: 'add_automation_using_tf', url: 'https://github.com/ShylajaDevadiga/k3s.git' + script { + dir("${WORKSPACE}/tests/terraform") { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + } + } + } + + stage('Configure') { + steps { + sh """ + set -e -x + echo 'aws_ami="${env.AWS_AMI}" + aws_user="${env.AWS_USER}" + region="${env.REGION}" + vpc_id="${env.VPC_ID}" + subnets="${env.SUBNETS}" + qa_space="${env.QA_SPACE}" + ec2_instance_class="${env.EC2_INSTANCE_CLASS}" + access_key="/config/$AWS_SSH_KEY_NAME" + no_of_worker_nodes="${env.NO_OF_WORKER_NODES}" + key_name="jenkins-rke-validation" + server_flags="${env.SERVER_FLAGS}" + worker_flags="${env.WORKER_FLAGS}" + k3s_version="${env.K3S_VERSION}" + availability_zone="${env.AVAILABILITY_ZONE}" + sg_id="${env.SG_ID}" + install_mode="${env.INSTALL_MODE}" + resource_name="${env.RESOURCE_NAME}" + no_of_server_nodes="${env.NO_OF_SERVER_NODES}" + username="${env.RHEL_USERNAME}" + password="${env.RHEL_PASSWORD}" + db_username="${env.DB_USERNAME}" + db_password="${env.DB_PASSWORD}" + node_os="${env.NODE_OS}" + environment="${env.ENVIRONMENT}" + engine_mode="${env.ENGINE_MODE}" + external_db="${env.EXTERNAL_DB}" + external_db_version="${env.EXTERNAL_DB_VERSION}" + instance_class="${env.DB_INSTANCE_CLASS}" + db_group_name="${env.DB_GROUP_NAME}" + cluster_type="${env.CLUSTER_TYPE}" + create_lb=${env.CREATE_LB} + ' >${WORKSPACE}/tests/terraform/${env.NODE_OS}${env.EXTERNAL_DB}".tfvars" + """ + } + } + stage('Build Cluster') { + steps { + sh """ + + /usr/bin/docker build -f tests/terraform/Dockerfile.build -t k3s_create_cluster . + + /usr/bin/docker run -d --name ${RESOURCE_NAME}_${BUILD_NUMBER} -v ${WORKSPACE}/tests/terraform:/config \ + -t -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ + k3s_create_cluster + + /usr/bin/docker cp "${WORKSPACE}/tests/terraform/${NODE_OS}${EXTERNAL_DB}".tfvars "${RESOURCE_NAME}_${BUILD_NUMBER}":/config + + /usr/bin/docker cp "${WORKSPACE}/tests/terraform/$AWS_SSH_KEY_NAME" "${RESOURCE_NAME}_${BUILD_NUMBER}":/config + + /usr/bin/docker exec ${RESOURCE_NAME}_${BUILD_NUMBER} /usr/local/go/bin/go test -v tests/terraform/createcluster.go \ + tests/terraform/createcluster_test.go tests/terraform/testutils.go -v \ + -timeout=2h -node_os=${NODE_OS} \ + -cluster_type=${CLUSTER_TYPE} -external_db=${EXTERNAL_DB} -resource_name=${RESOURCE_NAME} \ + -sshuser=${AWS_USER} -sshkey="/config/${AWS_SSH_KEY_NAME}" -destroy=false -arch=${ARCH} + + """ + } + } + + stage('Test Report') { + steps { + sh """ + /usr/bin/docker rm -f ${RESOURCE_NAME}_${BUILD_NUMBER} + /usr/bin/docker rmi -f k3s_create_cluster + """ + } + } + } + } \ No newline at end of file diff --git a/tests/terraform/modules/k3scluster/install_k3s_master.sh b/tests/terraform/modules/k3scluster/install_k3s_master.sh new file mode 100644 index 0000000000..af0ee3fda9 --- /dev/null +++ b/tests/terraform/modules/k3scluster/install_k3s_master.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +mkdir -p /etc/rancher/k3s +cat << EOF >/etc/rancher/k3s/config.yaml +write-kubeconfig-mode: "0644" +tls-san: + - ${2} +EOF + +if [[ -n "$8" ]] && [[ "$8" == *":"* ]] +then + echo "$" + echo -e "$8" >> /etc/rancher/k3s/config.yaml + cat /etc/rancher/k3s/config.yaml +fi + +if [ "${1}" = "rhel" ] +then + subscription-manager register --auto-attach --username="${9}" --password="${10}" + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi + +export "${3}"="${4}" + +if [ "${5}" = "etcd" ] +then + echo "CLUSTER TYPE is etcd" + if [[ "$4" == *"v1.18"* ]] || [["$4" == *"v1.17"* ]] && [[ -n "$8" ]] + then + echo "curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --cluster-init --node-external-ip=${6} $8" >/tmp/master_cmd + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --cluster-init --node-external-ip="${6}" "$8" + else + echo "curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --cluster-init --node-external-ip=${6}" >/tmp/master_cmd + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --cluster-init --node-external-ip="${6}" + fi +else + echo "CLUSTER TYPE is external db" + echo "$8" + if [[ "$4" == *"v1.18"* ]] || [[ "$4" == *"v1.17"* ]] && [[ -n "$8" ]] + then + echo "curl -sfL https://get.k3s.io | sh -s - server --node-external-ip=${6} --datastore-endpoint=\"${7}\" $8" >/tmp/master_cmd + curl -sfL https://get.k3s.io | sh -s - server --node-external-ip="${6}" --datastore-endpoint="${7}" "$8" + else + echo "curl -sfL https://get.k3s.io | sh -s - server --node-external-ip=${6} --datastore-endpoint=\"${7}\" " >/tmp/master_cmd + curl -sfL https://get.k3s.io | sh -s - server --node-external-ip="${6}" --datastore-endpoint="${7}" + fi +fi + +export PATH=$PATH:/usr/local/bin +timeElapsed=0 +while ! $(kubectl get nodes >/dev/null 2>&1) && [[ $timeElapsed -lt 300 ]] +do + sleep 5 + timeElapsed=$(expr $timeElapsed + 5) +done + +IFS=$'\n' +timeElapsed=0 +sleep 10 +while [[ $timeElapsed -lt 420 ]] +do + notready=false + for rec in $(kubectl get nodes) + do + if [[ "$rec" == *"NotReady"* ]] + then + notready=true + fi + done + if [[ $notready == false ]] + then + break + fi + sleep 20 + timeElapsed=$(expr $timeElapsed + 20) +done + +IFS=$'\n' +timeElapsed=0 +while [[ $timeElapsed -lt 420 ]] +do + helmPodsNR=false + systemPodsNR=false + for rec in $(kubectl get pods -A --no-headers) + do + if [[ "$rec" == *"helm-install"* ]] && [[ "$rec" != *"Completed"* ]] + then + helmPodsNR=true + elif [[ "$rec" != *"helm-install"* ]] && [[ "$rec" != *"Running"* ]] + then + systemPodsNR=true + else + echo "" + fi + done + + if [[ $systemPodsNR == false ]] && [[ $helmPodsNR == false ]] + then + break + fi + sleep 20 + timeElapsed=$(expr $timeElapsed + 20) +done +cat /etc/rancher/k3s/config.yaml> /tmp/joinflags +cat /var/lib/rancher/k3s/server/node-token >/tmp/nodetoken +cat /etc/rancher/k3s/k3s.yaml >/tmp/config diff --git a/tests/terraform/modules/k3scluster/join_k3s_agent.sh b/tests/terraform/modules/k3scluster/join_k3s_agent.sh new file mode 100644 index 0000000000..93c42fed0a --- /dev/null +++ b/tests/terraform/modules/k3scluster/join_k3s_agent.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# This script is used to join one or more nodes as agents + +mkdir -p /etc/rancher/k3s +cat <>/etc/rancher/k3s/config.yaml +server: https://${4}:6443 +token: "${5}" +EOF + +if [[ ! -z "$7" ]] && [[ "$7" == *":"* ]] +then + echo -e "$7" >> /etc/rancher/k3s/config.yaml + cat /etc/rancher/k3s/config.yaml +fi + +if [ ${1} = "rhel" ] +then + subscription-manager register --auto-attach --username=${8} --password=${9} + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi + +export "${2}"="${3}" + if [[ "$3" == *"v1.18"* ]] || [["$3" == *"v1.17"* ]] && [[ -n "$7" ]] +then + echo "curl -sfL https://get.k3s.io | sh -s - agent --node-external-ip=${6} $7" >/tmp/agent_cmd +curl -sfL https://get.k3s.io | sh -s - agent --node-external-ip=${6} ${7} + else + +echo "curl -sfL https://get.k3s.io | sh -s - agent --node-external-ip=${6}" >/tmp/agent_cmd +curl -sfL https://get.k3s.io | sh -s - agent --node-external-ip=${6} +fi diff --git a/tests/terraform/modules/k3scluster/join_k3s_master.sh b/tests/terraform/modules/k3scluster/join_k3s_master.sh new file mode 100644 index 0000000000..30ac201d08 --- /dev/null +++ b/tests/terraform/modules/k3scluster/join_k3s_master.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# This script is used to join one or more nodes as masters + +mkdir -p /etc/rancher/k3s +cat <>/etc/rancher/k3s/config.yaml +write-kubeconfig-mode: "0644" +tls-san: + - ${2} +EOF + +if [[ -n "${10}" ]] && [[ "${10}" == *":"* ]] +then + echo -e "${10}" >> /etc/rancher/k3s/config.yaml + cat /etc/rancher/k3s/config.yaml +fi + +if [ "${1}" = "rhel" ] +then + subscription-manager register --auto-attach --username="${11}" --password="${12}" + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi + +export "${3}"="${4}" + +if [ "${5}" = "etcd" ] +then + if [[ "$4" == *"v1.18"* ]] || [["$4" == *"v1.17"* ]] && [[ -n "$10" ]] + then + echo "curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --server https://\"${7}\":6443 --token \"${8}\" --node-external-ip=\"${6}\" ${10}" >/tmp/master_cmd + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --server https://"${7}":6443 --token "${8}" --node-external-ip="${6} ${10}" + else + echo "curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --server https://\"${7}\":6443 --token \"${8}\" --node-external-ip=\"${6}\"" >/tmp/master_cmd + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --server https://"${7}":6443 --token "${8}" --node-external-ip="${6}" + fi +else + if [[ "$4" == *"v1.18"* ]] || [["$4" == *"v1.17"* ]] && [[ -n "$10" ]] + then + echo "curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --node-external-ip=\"${6}\" --datastore-endpoint=\"${9}\" ${10}" >/tmp/master_cmd + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --node-external-ip="${6}" --token="${8}" --datastore-endpoint="${9} ${10}" + else + echo "curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --node-external-ip=\"${6}\" --token \"${8}\" --datastore-endpoint=\"${9}\"" >/tmp/master_cmd + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - --node-external-ip="${6}" --token="${8}" --datastore-endpoint="${9}" + fi +fi diff --git a/tests/terraform/modules/k3scluster/main.tf b/tests/terraform/modules/k3scluster/main.tf new file mode 100644 index 0000000000..592a5a63c4 --- /dev/null +++ b/tests/terraform/modules/k3scluster/main.tf @@ -0,0 +1,54 @@ +module "master" { + source="./master" + aws_ami=var.aws_ami + aws_user=var.aws_user + key_name=var.key_name + no_of_server_nodes=var.no_of_server_nodes + k3s_version=var.k3s_version + install_mode=var.install_mode + region=var.region + vpc_id=var.vpc_id + subnets=var.subnets + qa_space=var.qa_space + ec2_instance_class=var.ec2_instance_class + access_key=var.access_key + cluster_type=var.cluster_type + server_flags=var.server_flags + availability_zone=var.availability_zone + sg_id=var.sg_id + resource_name=var.resource_name + node_os=var.node_os + username=var.username + password=var.password + db_username=var.db_username + db_password=var.db_password + db_group_name=var.db_group_name + external_db=var.external_db + instance_class=var.instance_class + external_db_version=var.external_db_version + engine_mode=var.engine_mode + environment=var.environment + create_lb=var.create_lb +} +module "worker" { + source="./worker" + dependency = module.master + aws_ami=var.aws_ami + aws_user=var.aws_user + key_name=var.key_name + no_of_worker_nodes=var.no_of_worker_nodes + k3s_version=var.k3s_version + install_mode=var.install_mode + region=var.region + vpc_id=var.vpc_id + subnets=var.subnets + ec2_instance_class=var.ec2_instance_class + access_key=var.access_key + worker_flags=var.worker_flags + availability_zone=var.availability_zone + sg_id=var.sg_id + resource_name=var.resource_name + node_os=var.node_os + username=var.username + password=var.password +} diff --git a/tests/terraform/modules/k3scluster/master/instances_server.tf b/tests/terraform/modules/k3scluster/master/instances_server.tf new file mode 100644 index 0000000000..8cf3b31a67 --- /dev/null +++ b/tests/terraform/modules/k3scluster/master/instances_server.tf @@ -0,0 +1,296 @@ +resource "aws_db_instance" "db" { + count = (var.cluster_type == "etcd" ? 0 : (var.external_db != "aurora-mysql" ? 1 : 0)) + identifier = "${var.resource_name}-db" + allocated_storage = 20 + storage_type = "gp2" + engine = var.external_db + engine_version = var.external_db_version + instance_class = var.instance_class + name = "mydb" + parameter_group_name = var.db_group_name + username = var.db_username + password = var.db_password + availability_zone = var.availability_zone + tags = { + Environment = var.environment + } + skip_final_snapshot = true +} + +resource "aws_rds_cluster" "db" { + count = (var.external_db == "aurora-mysql" ? 1 : 0) + cluster_identifier = "${var.resource_name}-db" + engine = var.external_db + engine_version = var.external_db_version + availability_zones = [var.availability_zone] + database_name = "mydb" + master_username = var.db_username + master_password = var.db_password + engine_mode = var.engine_mode + tags = { + Environment = var.environment + } + skip_final_snapshot = true +} + +resource "aws_rds_cluster_instance" "db" { + count = (var.external_db == "aurora-mysql" ? 1 : 0) + cluster_identifier = "${aws_rds_cluster.db[0].id}" + identifier = "${var.resource_name}-instance1" + instance_class = var.instance_class + engine = aws_rds_cluster.db[0].engine + engine_version = aws_rds_cluster.db[0].engine_version +} + +resource "aws_instance" "master" { + ami = var.aws_ami + instance_type = var.ec2_instance_class + connection { + type = "ssh" + user = var.aws_user + host = self.public_ip + private_key = file(var.access_key) + } + root_block_device { + volume_size = "20" + volume_type = "standard" + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = [var.sg_id] + key_name = var.key_name + tags = { + Name = "${var.resource_name}-server" + } + provisioner "file" { + source = "install_k3s_master.sh" + destination = "/tmp/install_k3s_master.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/install_k3s_master.sh", + "sudo /tmp/install_k3s_master.sh ${var.node_os} ${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : "${aws_instance.master.public_ip}"} ${var.install_mode} ${var.k3s_version} ${var.cluster_type} ${self.public_ip} \"${data.template_file.test.rendered}\" \"${var.server_flags}\" ${var.username} ${var.password}", + ] + } + provisioner "local-exec" { + command = "echo ${aws_instance.master.public_ip} >/tmp/${var.resource_name}_master_ip" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/nodetoken /tmp/${var.resource_name}_nodetoken" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/config /tmp/${var.resource_name}_config" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/joinflags /tmp/${var.resource_name}_joinflags" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/master_cmd /tmp/${var.resource_name}_master_cmd" + } + provisioner "local-exec" { + command = "sed s/127.0.0.1/\"${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : aws_instance.master.public_ip}\"/g /tmp/${var.resource_name}_config >/tmp/${var.resource_name}_kubeconfig" + } + provisioner "local-exec" { + command = "sed s/127.0.0.1/\"${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : aws_instance.master.public_ip}\"/g /tmp/${var.resource_name}_config >/config/${var.resource_name}_kubeconfig" + } +} + +data "template_file" "test" { + template = (var.cluster_type == "etcd" ? "NULL": (var.external_db == "postgres" ? "postgres://${aws_db_instance.db[0].username}:${aws_db_instance.db[0].password}@${aws_db_instance.db[0].endpoint}/${aws_db_instance.db[0].name}" : (var.external_db == "aurora-mysql" ? "mysql://${aws_rds_cluster.db[0].master_username}:${aws_rds_cluster.db[0].master_password}@tcp(${aws_rds_cluster.db[0].endpoint})/${aws_rds_cluster.db[0].database_name}" : "mysql://${aws_db_instance.db[0].username}:${aws_db_instance.db[0].password}@tcp(${aws_db_instance.db[0].endpoint})/${aws_db_instance.db[0].name}"))) + depends_on = [data.template_file.test_status] +} + +data "template_file" "test_status" { + template = (var.cluster_type == "etcd" ? "NULL": ((var.external_db == "postgres" ? aws_db_instance.db[0].endpoint : (var.external_db == "aurora-mysql" ? aws_rds_cluster_instance.db[0].endpoint : aws_db_instance.db[0].endpoint)))) +} + +data "local_file" "token" { + filename = "/tmp/${var.resource_name}_nodetoken" + depends_on = [aws_instance.master] +} + +locals { + node_token = trimspace("${data.local_file.token.content}") +} + +resource "aws_instance" "master2-ha" { + ami = var.aws_ami + instance_type = var.ec2_instance_class + count = var.no_of_server_nodes + connection { + type = "ssh" + user = var.aws_user + host = self.public_ip + private_key = file(var.access_key) + } + root_block_device { + volume_size = "20" + volume_type = "standard" + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = [var.sg_id] + key_name = var.key_name + depends_on = [aws_instance.master] + tags = { + Name = "${var.resource_name}-servers" + } + provisioner "file" { + source = "join_k3s_master.sh" + destination = "/tmp/join_k3s_master.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/join_k3s_master.sh", + "sudo /tmp/join_k3s_master.sh ${var.node_os} ${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : "${aws_instance.master.public_ip}"} ${var.install_mode} ${var.k3s_version} ${var.cluster_type} ${self.public_ip} ${aws_instance.master.public_ip} ${local.node_token} \"${data.template_file.test.rendered}\" \"${var.server_flags}\" ${var.username} ${var.password}", + ] + } +} + +resource "aws_lb_target_group" "aws_tg_80" { + count = var.create_lb ? 1 : 0 + port = 80 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-80" + health_check { + protocol = "HTTP" + port = "traffic-port" + path = "/ping" + interval = 10 + timeout = 6 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-399" + } +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_80" { + count = var.create_lb ? 1 : 0 + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + target_id = "${aws_instance.master.id}" + port = 80 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_80_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + count = var.create_lb ? length(aws_instance.master2-ha) : 0 + target_id = "${aws_instance.master2-ha[count.index].id}" + port = 80 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb_target_group" "aws_tg_443" { + count = var.create_lb ? 1 : 0 + port = 443 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-443" + health_check { + protocol = "HTTP" + port = 80 + path = "/ping" + interval = 10 + timeout = 6 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-399" + } +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_443" { + count = var.create_lb ? 1 : 0 + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + target_id = "${aws_instance.master.id}" + port = 443 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_443_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + count = var.create_lb ? length(aws_instance.master2-ha) : 0 + target_id = "${aws_instance.master2-ha[count.index].id}" + port = 443 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb_target_group" "aws_tg_6443" { + count = var.create_lb ? 1 : 0 + port = 6443 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-6443" +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_6443" { + count = var.create_lb ? 1 : 0 + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + target_id = "${aws_instance.master.id}" + port = 6443 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_6443_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + count = var.create_lb ? length(aws_instance.master2-ha) : 0 + target_id = "${aws_instance.master2-ha[count.index].id}" + port = 6443 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb" "aws_nlb" { + count = var.create_lb ? 1 : 0 + internal = false + load_balancer_type = "network" + subnets = ["${var.subnets}"] + name = "${var.resource_name}-nlb" +} + +resource "aws_lb_listener" "aws_nlb_listener_80" { + count = var.create_lb ? 1 : 0 + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "80" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + } +} + +resource "aws_lb_listener" "aws_nlb_listener_443" { + count = var.create_lb ? 1 : 0 + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "443" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + } +} + +resource "aws_lb_listener" "aws_nlb_listener_6443" { + count = var.create_lb ? 1 : 0 + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "6443" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + } +} + +resource "aws_route53_record" "aws_route53" { + count = var.create_lb ? 1 : 0 + zone_id = "${data.aws_route53_zone.selected.zone_id}" + name = "${var.resource_name}" + type = "CNAME" + ttl = "300" + records = ["${aws_lb.aws_nlb[0].dns_name}"] + depends_on = ["aws_lb_listener.aws_nlb_listener_6443"] +} + +data "aws_route53_zone" "selected" { + name = "${var.qa_space}" + private_zone = false +} diff --git a/tests/terraform/modules/k3scluster/master/outputs.tf b/tests/terraform/modules/k3scluster/master/outputs.tf new file mode 100644 index 0000000000..0f867e0ff3 --- /dev/null +++ b/tests/terraform/modules/k3scluster/master/outputs.tf @@ -0,0 +1,14 @@ +output "Route53_info" { + value = aws_route53_record.aws_route53.* + description = "List of DNS records" +} + +output "master_ips" { + value = join("," , aws_instance.master.*.public_ip,aws_instance.master2-ha.*.public_ip) + description = "The public IP of the AWS node" +} + +output "kubeconfig" { + value = var.resource_name + description = "kubeconfig of the cluster created" +} diff --git a/tests/terraform/modules/k3scluster/master/providers.tf b/tests/terraform/modules/k3scluster/master/providers.tf new file mode 100644 index 0000000000..0ced9d7521 --- /dev/null +++ b/tests/terraform/modules/k3scluster/master/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "${var.region}" +} diff --git a/tests/terraform/modules/k3scluster/master/variables.tf b/tests/terraform/modules/k3scluster/master/variables.tf new file mode 100644 index 0000000000..eabd978ae7 --- /dev/null +++ b/tests/terraform/modules/k3scluster/master/variables.tf @@ -0,0 +1,36 @@ +variable "aws_ami" {} +variable "aws_user" {} +variable "region" {} +variable "access_key" {} +variable "vpc_id" {} +variable "subnets" {} +variable "availability_zone" {} +variable "sg_id" {} +variable "qa_space" {} +variable "ec2_instance_class" {} +variable "resource_name" {} +variable "key_name" {} + +variable "external_db" {} +variable "external_db_version" {} +variable "instance_class" {} + +variable "db_group_name" {} +variable "username" {} +variable "password" {} +variable "k3s_version" {} +variable "no_of_server_nodes" {} +variable "server_flags" {} + +variable "cluster_type" {} +variable "node_os" {} +variable "db_username" {} +variable "db_password" {} +variable "environment" {} +variable "engine_mode" {} +variable "install_mode" {} + +variable "create_lb" { + description = "Create Network Load Balancer if set to true" + type = bool +} diff --git a/tests/terraform/modules/k3scluster/outputs.tf b/tests/terraform/modules/k3scluster/outputs.tf new file mode 100644 index 0000000000..6c5d8c9792 --- /dev/null +++ b/tests/terraform/modules/k3scluster/outputs.tf @@ -0,0 +1,14 @@ +output "master_ips" { + value = module.master.master_ips + description = "The public IP of the AWS node" +} + +output "worker_ips" { + value = module.worker.worker_ips + description = "The public IP of the AWS node" +} + +output "kubeconfig" { + value = module.master.kubeconfig + description = "kubeconfig of the cluster created" +} diff --git a/tests/terraform/modules/k3scluster/providers.tf b/tests/terraform/modules/k3scluster/providers.tf new file mode 100644 index 0000000000..0ced9d7521 --- /dev/null +++ b/tests/terraform/modules/k3scluster/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "${var.region}" +} diff --git a/tests/terraform/modules/k3scluster/variables.tf b/tests/terraform/modules/k3scluster/variables.tf new file mode 100644 index 0000000000..e0c07197d3 --- /dev/null +++ b/tests/terraform/modules/k3scluster/variables.tf @@ -0,0 +1,35 @@ +#variable "db" {} +variable "no_of_worker_nodes" {} +variable "aws_ami" {} +variable "aws_user" {} +variable "region" {} +variable "access_key" {} +variable "vpc_id" {} +variable "subnets" {} +variable "qa_space" {} +variable "resource_name" {} +variable "key_name" {} +variable "external_db" {} +variable "external_db_version" {} +variable "instance_class" {} +variable "ec2_instance_class" {} +variable "db_group_name" {} +variable "username" {} +variable "password" {} +variable "k3s_version" {} +variable "no_of_server_nodes" {} +variable "server_flags" {} +variable "worker_flags" {} +variable "availability_zone" {} +variable "sg_id" {} +variable "cluster_type" {} +variable "node_os" {} +variable "db_username" {} +variable "db_password" {} +variable "environment" {} +variable "engine_mode" {} +variable "install_mode" {} +variable "create_lb" { + description = "Create Network Load Balancer if set to true" + type = bool +} \ No newline at end of file diff --git a/tests/terraform/modules/k3scluster/worker/instances_worker.tf b/tests/terraform/modules/k3scluster/worker/instances_worker.tf new file mode 100644 index 0000000000..59b40fdc62 --- /dev/null +++ b/tests/terraform/modules/k3scluster/worker/instances_worker.tf @@ -0,0 +1,49 @@ +resource "aws_instance" "worker" { + depends_on = [ + var.dependency + ] + ami = var.aws_ami + instance_type = var.ec2_instance_class + count = var.no_of_worker_nodes + connection { + type = "ssh" + user = var.aws_user + host = self.public_ip + private_key = file(var.access_key) + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = [var.sg_id] + key_name = var.key_name + tags = { + Name = "${var.resource_name}-worker" + } + provisioner "file" { + source = "join_k3s_agent.sh" + destination = "/tmp/join_k3s_agent.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/join_k3s_agent.sh", + "sudo /tmp/join_k3s_agent.sh ${var.node_os} ${var.install_mode} ${var.k3s_version} ${local.master_ip} ${local.node_token} ${self.public_ip} \"${var.worker_flags}\" ${var.username} ${var.password} ", + ] + } +} + +data "local_file" "master_ip" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_master_ip" +} + +locals { + master_ip = trimspace(data.local_file.master_ip.content) +} + +data "local_file" "token" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_nodetoken" +} + +locals { + node_token = trimspace(data.local_file.token.content) +} diff --git a/tests/terraform/modules/k3scluster/worker/outputs.tf b/tests/terraform/modules/k3scluster/worker/outputs.tf new file mode 100644 index 0000000000..145541c4c2 --- /dev/null +++ b/tests/terraform/modules/k3scluster/worker/outputs.tf @@ -0,0 +1,12 @@ +output "Registration_address" { + value = "${data.local_file.master_ip.content}" +} + +output "master_node_token" { + value = "${data.local_file.token.content}" +} + +output "worker_ips" { + value = join("," , aws_instance.worker.*.public_ip) + description = "The public IP of the AWS node" +} diff --git a/tests/terraform/modules/k3scluster/worker/providers.tf b/tests/terraform/modules/k3scluster/worker/providers.tf new file mode 100644 index 0000000000..0ced9d7521 --- /dev/null +++ b/tests/terraform/modules/k3scluster/worker/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "${var.region}" +} diff --git a/tests/terraform/modules/k3scluster/worker/variables.tf b/tests/terraform/modules/k3scluster/worker/variables.tf new file mode 100644 index 0000000000..b5d6979324 --- /dev/null +++ b/tests/terraform/modules/k3scluster/worker/variables.tf @@ -0,0 +1,22 @@ +variable "dependency" { + type = any + default = null +} +variable "region" {} +variable "aws_ami" {} +variable "aws_user" {} +variable "vpc_id" {} +variable "subnets" {} +variable "resource_name" {} +variable "access_key" {} +variable "k3s_version" {} +variable "no_of_worker_nodes" {} +variable "worker_flags" {} +variable "ec2_instance_class" {} +variable "availability_zone" {} +variable "sg_id" {} +variable "username" {} +variable "password" {} +variable "node_os" {} +variable "install_mode" {} +variable "key_name" {} diff --git a/tests/terraform/scripts/build.sh b/tests/terraform/scripts/build.sh new file mode 100755 index 0000000000..a17115efe1 --- /dev/null +++ b/tests/terraform/scripts/build.sh @@ -0,0 +1 @@ +/usr/local/bin/docker build -f Dockerfile.build -t k3s_create_cluster . diff --git a/tests/terraform/testutils.go b/tests/terraform/testutils.go new file mode 100644 index 0000000000..30ca49e558 --- /dev/null +++ b/tests/terraform/testutils.go @@ -0,0 +1,224 @@ +package e2e + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "os/exec" + "path/filepath" + "strings" + "time" + + "golang.org/x/crypto/ssh" +) + +type Node struct { + Name string + Status string + Roles string + InternalIP string + ExternalIP string +} + +type Pod struct { + NameSpace string + Name string + Ready string + Status string + Restarts string + NodeIP string + Node string +} + +var config *ssh.ClientConfig +var SSHKEY string +var SSHUSER string +var err error + +func checkError(e error) { + if e != nil { + log.Fatal(err) + panic(e) + } +} + +func publicKey(path string) ssh.AuthMethod { + key, err := ioutil.ReadFile(path) + if err != nil { + panic(err) + } + signer, err := ssh.ParsePrivateKey(key) + if err != nil { + panic(err) + } + return ssh.PublicKeys(signer) +} + +func ConfigureSSH(host string, SSHUser string, SSHKey string) *ssh.Client { + config = &ssh.ClientConfig{ + User: SSHUser, + Auth: []ssh.AuthMethod{ + publicKey(SSHKey), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + } + conn, err := ssh.Dial("tcp", host, config) + checkError(err) + return conn +} + +func runsshCommand(cmd string, conn *ssh.Client) (string, error) { + session, err := conn.NewSession() + if err != nil { + panic(err) + } + defer session.Close() + var stdoutBuf bytes.Buffer + var stderrBuf bytes.Buffer + session.Stdout = &stdoutBuf + session.Stderr = &stderrBuf + return fmt.Sprintf("%s", stdoutBuf.String()), err +} + +// nodeOs: ubuntu centos7 centos8 sles15 +// clusterType arm, etcd externaldb, if external_db var is not "" picks database from the vars file, +// resourceName: name to resource created timestamp attached + +// RunCmdOnNode executes a command from within the given node +func RunCmdOnNode(cmd string, ServerIP string, SSHUser string, SSHKey string) (string, error) { + Server := ServerIP + ":22" + fmt.Println(Server, SSHUser, SSHKey) + conn := ConfigureSSH(Server, SSHUser, SSHKey) + res, err := runsshCommand(cmd, conn) + res = strings.TrimSpace(res) + return res, err +} + +// RunCommand executes a command on the host +func RunCommand(cmd string) (string, error) { + c := exec.Command("bash", "-c", cmd) + out, err := c.CombinedOutput() + return string(out), err +} + +//Used to count the pods using prefix passed in the list of pods +func CountOfStringInSlice(str string, pods []Pod) int { + count := 0 + for _, pod := range pods { + if strings.Contains(pod.Name, str) { + count++ + } + } + return count +} + +func DeployWorkload(workload, kubeconfig string, arch bool) (string, error) { + resourceDir := "./amd64_resource_files" + if arch { + resourceDir = "./arm64_resource_files" + } + files, err := ioutil.ReadDir(resourceDir) + if err != nil { + err = fmt.Errorf("%s : Unable to read resource manifest file for %s", err, workload) + return "", err + } + fmt.Println("\nDeploying", workload) + for _, f := range files { + filename := filepath.Join(resourceDir, f.Name()) + if strings.TrimSpace(f.Name()) == workload { + cmd := "kubectl apply -f " + filename + " --kubeconfig=" + kubeconfig + fmt.Println(cmd) + return RunCommand(cmd) + } + } + return "", nil +} + +func FetchClusterIP(kubeconfig string, servicename string) (string, error) { + cmd := "kubectl get svc " + servicename + " -o jsonpath='{.spec.clusterIP}' --kubeconfig=" + kubeconfig + fmt.Println(cmd) + return RunCommand(cmd) +} + +func FetchNodeExternalIP(kubeconfig string) []string { + cmd := "kubectl get node --output=jsonpath='{range .items[*]} { .status.addresses[?(@.type==\"ExternalIP\")].address}' --kubeconfig=" + kubeconfig + time.Sleep(10 * time.Second) + res, _ := RunCommand(cmd) + nodeExternalIP := strings.Trim(res, " ") + nodeExternalIPs := strings.Split(nodeExternalIP, " ") + return nodeExternalIPs +} + +func FetchIngressIP(kubeconfig string) ([]string, error) { + cmd := "kubectl get ingress -o jsonpath='{.items[0].status.loadBalancer.ingress[*].ip}' --kubeconfig=" + kubeconfig + fmt.Println(cmd) + res, err := RunCommand(cmd) + if err != nil { + return nil, err + } + ingressIP := strings.Trim(res, " ") + fmt.Println(ingressIP) + ingressIPs := strings.Split(ingressIP, " ") + return ingressIPs, nil +} + +func ParseNodes(kubeConfig string, print bool) ([]Node, error) { + nodes := make([]Node, 0, 10) + nodeList := "" + + cmd := "kubectl get nodes --no-headers -o wide -A --kubeconfig=" + kubeConfig + res, err := RunCommand(cmd) + + if err != nil { + return nil, err + } + nodeList = strings.TrimSpace(res) + split := strings.Split(nodeList, "\n") + for _, rec := range split { + if strings.TrimSpace(rec) != "" { + fields := strings.Fields(rec) + node := Node{ + Name: fields[0], + Status: fields[1], + Roles: fields[2], + InternalIP: fields[5], + ExternalIP: fields[6], + } + nodes = append(nodes, node) + } + } + if print { + fmt.Println(nodeList) + } + return nodes, nil +} + +func ParsePods(kubeconfig string, print bool) ([]Pod, error) { + pods := make([]Pod, 0, 10) + podList := "" + + cmd := "kubectl get pods -o wide --no-headers -A --kubeconfig=" + kubeconfig + res, _ := RunCommand(cmd) + res = strings.TrimSpace(res) + podList = res + + split := strings.Split(res, "\n") + for _, rec := range split { + fields := strings.Fields(string(rec)) + pod := Pod{ + NameSpace: fields[0], + Name: fields[1], + Ready: fields[2], + Status: fields[3], + Restarts: fields[4], + NodeIP: fields[6], + Node: fields[7], + } + pods = append(pods, pod) + } + if print { + fmt.Println(podList) + } + return pods, nil +}