diff --git a/.golangci.yaml b/.golangci.yaml index 678194676..b3178d2be 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -7,7 +7,7 @@ run: concurrency: 4 # timeout for analysis, e.g. 30s, 5m, default is 1m - deadline: 1m + deadline: 5m # exit code when at least one issue was found, default is 1 issues-exit-code: 1 @@ -133,6 +133,7 @@ linters-settings: for-loops: false # Report preallocation suggestions on for loops, false by default linters: + disable-all: true enable: - dupl # Tool for code clone detection - goconst # Finds repeated strings that could be replaced by a constant diff --git a/go.mod b/go.mod index 42b73875c..f8d52ee6a 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/Azure/go-autorest/autorest v0.2.0 // indirect github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e // indirect github.com/Microsoft/go-winio v0.4.12 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/argoproj/argo v2.3.0+incompatible github.com/argoproj/pkg v0.0.0-20190409001913-7e3ef65c8d44 // indirect github.com/blang/semver v3.5.1+incompatible // indirect @@ -27,20 +26,15 @@ require ( github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect - github.com/evanphx/json-patch v4.1.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect - github.com/go-openapi/spec v0.19.0 // indirect - github.com/gogo/protobuf v1.2.1 // indirect github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect github.com/golangci/golangci-lint v1.18.0 github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 // indirect github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 // indirect github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e // indirect github.com/google/btree v1.0.0 // indirect - github.com/google/gofuzz v1.0.0 // indirect - github.com/googleapis/gnostic v0.2.0 // indirect github.com/gophercloud/gophercloud v0.1.0 // indirect github.com/gorilla/mux v1.7.2 // indirect github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect @@ -50,12 +44,10 @@ require ( github.com/imdario/mergo v0.3.7 // indirect github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03 // indirect github.com/jonboulle/clockwork v0.1.0 // indirect - github.com/json-iterator/go v1.1.6 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/lithammer/dedent v1.1.0 // indirect github.com/mholt/caddy v1.0.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect - github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0-rc1 // indirect @@ -66,7 +58,7 @@ require ( github.com/sirupsen/logrus v1.4.1 // indirect github.com/soheilhy/cmux v0.1.4 // indirect github.com/spf13/cobra v0.0.3 - github.com/spf13/pflag v1.0.3 // indirect + github.com/stretchr/testify v1.3.0 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect github.com/valyala/fasttemplate v1.0.1 // indirect github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e // indirect @@ -77,11 +69,8 @@ require ( go.uber.org/atomic v1.4.0 // indirect go.uber.org/multierr v1.1.0 // indirect go.uber.org/zap v1.10.0 // indirect - golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect - golang.org/x/sys v0.0.0-20190422165155-953cdadca894 // indirect golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect gopkg.in/jcmturner/goidentity.v2 v2.0.0 // indirect @@ -97,14 +86,13 @@ require ( k8s.io/cloud-provider v0.0.0-20190516232619-2bf8e45c8454 // indirect k8s.io/cluster-bootstrap v0.0.0-20190516232516-d7d78ab2cfe7 // indirect k8s.io/component-base v0.0.0-20190516230545-9b07ebd4193b // indirect - k8s.io/klog v0.3.2 // indirect - k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208 // indirect k8s.io/kube-proxy v0.0.0-20190516232141-b2acb7b92548 // indirect k8s.io/kubelet v0.0.0-20190516232236-412e4380c1a8 // indirect k8s.io/kubernetes v1.14.2 k8s.io/metrics v0.0.0-20190516231729-8b83d5daaa8f // indirect k8s.io/utils v0.0.0-20190529001817-6999998975a7 // indirect sigs.k8s.io/kustomize v2.0.3+incompatible // indirect + sigs.k8s.io/kustomize/v3 v3.2.0 sigs.k8s.io/yaml v1.1.0 vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect ) diff --git a/go.sum b/go.sum index 6a8677197..b573f27fd 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,7 @@ github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcy github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2 h1:HTOmFEEYrWi4MW5ZKUx6xfeyM10Sx3kQF65xiQJMPYA= github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= +github.com/OpenPeeDeeP/depguard v1.0.0 h1:k9QF73nrHT3nPLz3lu6G5s+3Hi8Je36ODr1F5gjAXXM= github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= @@ -102,8 +103,12 @@ github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f h1:AUj1VoZUfhP github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w= +github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/evanphx/json-patch v4.1.0+incompatible h1:K1MDoo4AZ4wU0GIU/fPmtZg7VpzLjCxu+UwBD1FvwOc= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= @@ -122,6 +127,7 @@ github.com/go-acme/lego v2.5.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG github.com/go-critic/go-critic v0.0.0-20181204210945-c3db6069acc5/go.mod h1:Jc75BZJv2dNy7opKH6bF29VveDQHfGZ6Asn/3phBesg= github.com/go-critic/go-critic v0.0.0-20181204210945-ee9bf5809ead h1:qwmAYufKDopQnFdeMw+iHJVxAd2CbF+VFKHyJJwnPKk= github.com/go-critic/go-critic v0.0.0-20181204210945-ee9bf5809ead/go.mod h1:3MzXZKJdeXqdU9cj+rvZdNiN7SZ8V9OjybF8loZDmHU= +github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540 h1:djv/qAomOVj8voCHt0M0OYwR/4vfDq1zNKSPKjJCexs= github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= @@ -131,31 +137,44 @@ github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dT github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4= github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-toolsmith/astcast v0.0.0-20181028201508-b7a89ed70af1 h1:h+1eMw+tZAlgTVclcVN0/rdPaBI/RUzG0peblT6df+Q= github.com/go-toolsmith/astcast v0.0.0-20181028201508-b7a89ed70af1/go.mod h1:TEo3Ghaj7PsZawQHxT/oBvo4HK/sl1RcuUHDKTTju+o= +github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v0.0.0-20180903214859-79b422d080c4 h1:wVs9OMjICHbAryp9hcIuWqUOi+NqEbUSZy9zMe3W//I= github.com/go-toolsmith/astcopy v0.0.0-20180903214859-79b422d080c4/go.mod h1:c9CPdq2AzM8oPomdlPniEfPAC6g1s7NqZzODt8y6ib8= +github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6 h1:aTBUNRTatDDU24gbOEKEoLiDwxtc98ga6K/iMTm6fvs= github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086 h1:EIMuvbE9fbtQtimdLe5yeXjuC5CeKbQt8zH6GwtIrhM= github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30 h1:zRJPftZJNLPDiOtvYbFRwjSbaJAcVOf80TeEmWGe2kQ= github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= github.com/go-toolsmith/pkgload v0.0.0-20181120203407-5122569a890b h1:M3arPs33ilAwsEZcEzBcZGj5XjNLo1Qohmg0IkSmrnA= @@ -163,9 +182,11 @@ github.com/go-toolsmith/pkgload v0.0.0-20181120203407-5122569a890b/go.mod h1:WoM github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= github.com/go-toolsmith/strparse v0.0.0-20180903215201-830b6daa1241 h1:ZRDeQioMGTBLeJxcPxXfFifEUgYxzR7fXw7w2WR+1bo= github.com/go-toolsmith/strparse v0.0.0-20180903215201-830b6daa1241/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v0.0.0-20181030061450-d63dc7650676 h1:6Qrsp0+25KEkaS2bB26UE0giFgRrIc8mYXboDL5OVMA= github.com/go-toolsmith/typep v0.0.0-20181030061450-d63dc7650676/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA= github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= @@ -193,11 +214,13 @@ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9 github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= github.com/golangci/errcheck v0.0.0-20181003203344-ef45e06d44b6 h1:i2jIkQFb8RG45DuQs+ElyROY848cSJIoIkBM+7XXypA= github.com/golangci/errcheck v0.0.0-20181003203344-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= +github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= github.com/golangci/go-tools v0.0.0-20180109140146-af6baa5dc196 h1:9rtVlONXLF1rJZzvLt4tfOXtnAFUEhxCJ64Ibzj6ECo= github.com/golangci/go-tools v0.0.0-20180109140146-af6baa5dc196/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM= +github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c h1:/7detzz5stiXWPzkTlPTzkBEIIE4WGpppBJYjKqBiPI= github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM= github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= @@ -205,20 +228,25 @@ github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70u github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= github.com/golangci/gofmt v0.0.0-20181105071733-0b8337e80d98 h1:ir6/L2ZOJfFrJlOTsuf/hlzdPuUwXV/VzkSlgS6f1vs= github.com/golangci/gofmt v0.0.0-20181105071733-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98 h1:0OkFarm1Zy2CjCiDKfK9XHgmc2wbDlRMD2hD8anAJHU= github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= github.com/golangci/golangci-lint v1.16.1-0.20190425135923-692dacb773b7 h1:RfttK8W9qaF98OAdNFW2Mbr3ELn1Dyw1nnip6kYVc8M= github.com/golangci/golangci-lint v1.16.1-0.20190425135923-692dacb773b7/go.mod h1:kSe2pu2LlcsMT5Dr95yNKUT5RNfMkwif9MZqtOW5NEs= +github.com/golangci/golangci-lint v1.18.0 h1:XmQgfcLofSG/6AsQuQqmLizB+3GggD+o6ObBG9L+VMM= github.com/golangci/golangci-lint v1.18.0/go.mod h1:kaqo8l0OZKYPtjNmG4z4HrWLgcYNIJ9B9q3LWri9uLg= github.com/golangci/gosec v0.0.0-20180901114220-66fb7fc33547 h1:qMomh8bv+kDazm1dSLZ9S3zZ2PJZMHL4ilfBjxFOlmI= github.com/golangci/gosec v0.0.0-20180901114220-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU= github.com/golangci/gosec v0.0.0-20180901114220-8afd9cbb6cfb h1:Bi7BYmZVg4C+mKGi8LeohcP2GGUl2XJD4xCkJoZSaYc= github.com/golangci/gosec v0.0.0-20180901114220-8afd9cbb6cfb/go.mod h1:ON/c2UR0VAAv6ZEAFKhjCLplESSmRFfZcDLASbI1GWo= +github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547 h1:fUdgm/BdKvwOHxg5AhNbkNRp2mSy8sxTXyBVs/laQHo= github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU= github.com/golangci/ineffassign v0.0.0-20180808204949-2ee8f2867dde h1:qEGp3ZF1Qw6TkbWKn6GdJ12Ssu/CpJBaBcJ4hrUjrSo= github.com/golangci/ineffassign v0.0.0-20180808204949-2ee8f2867dde/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= +github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= github.com/golangci/lint-1 v0.0.0-20180610141402-ee948d087217 h1:r7vyX+SN24x6+5AnpnrRn/bdwBb7U+McZqCHOVtXDuk= github.com/golangci/lint-1 v0.0.0-20180610141402-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217 h1:En/tZdwhAn0JNwLuXzP3k2RVtMqMmOEK7Yu/g3tmtJE= github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= @@ -249,6 +277,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.3.0 h1:CcQijm0XKekKjP/YCz28LXVSpgguuB+nCxaSjCe09y0= +github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -257,6 +287,7 @@ github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -303,6 +334,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= @@ -320,6 +352,9 @@ github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481 h1:IaSjLMT6WvkoZZjspGxy3rdaTEmWLoRm49WbtVUi9sA= +github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -344,6 +379,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= @@ -441,14 +478,17 @@ github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso= github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec h1:AmoEvWAO3nDx1MEcMzPh+GzOOIA5Znpv6++c7bePPY0= github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ultraware/funlen v0.0.1 h1:UeC9tpM4wNWzUJfan8z9sFE4QCzjjzlCZmuJN+aOkH0= github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -485,6 +525,8 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a h1:YX8ljsm6wXlHZO+aRz9Exq golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd h1:sMHc2rZHuzQmrbVoSpt9HgerkXPyIeCSO6k0zUMGfFk= golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -507,6 +549,7 @@ golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190420063019-afa5a82059c6 h1:HdqqaWmYAUI7/dmByKKEw+yxDksGSo+9GjkUc9Zp34E= golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= @@ -537,15 +580,21 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190621203818-d432491b9138 h1:t8BZD9RDjkm9/h7yYN6kE8oaeov5r9aztkB7zKA5Tkg= +golang.org/x/sys v0.0.0-20190621203818-d432491b9138/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181024171208-a2dc47679d30/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -561,6 +610,8 @@ golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190420000508-685fecacd0a0 h1:pa1CyBALPFjblgkNQp7T7gEcFcG/GOG5Ck8IcnSVWGs= golang.org/x/tools v0.0.0-20190420000508-685fecacd0a0/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190909030654-5b82db07426d h1:PhtdWYteEBebOX7KXm4qkIAVSUTHQ883/2hRB92r9lk= golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= @@ -612,16 +663,19 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.0.0-20190313235455-40a48860b5ab/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/api v0.0.0-20190516230258-a675ac48af67 h1:BKg03K4me3EdM340RB08XB3MRlJ57KY+0f5PfI6wPZY= k8s.io/api v0.0.0-20190516230258-a675ac48af67/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/apiextensions-apiserver v0.0.0-20190516231611-bf6753f2aa24 h1:SwpU8lyfh7Orv1XmveHiN6AD2LxffLHLePQ2gcav4sk= k8s.io/apiextensions-apiserver v0.0.0-20190516231611-bf6753f2aa24/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d h1:Jmdtdt1ZnoGfWWIIik61Z7nKYgO3J+swQJtPYsP9wHA= k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= k8s.io/apiserver v0.0.0-20190516230822-f89599b3f645 h1:oMjWLjIo6BCIsay+j5r8WbEoHA3Chn/s9duoqXEGzRw= k8s.io/apiserver v0.0.0-20190516230822-f89599b3f645/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w= k8s.io/cli-runtime v0.0.0-20190516231937-17bc0b7fcef5 h1:kSosNyQ/BwwdA3MsCX8wIhdELKQ0P4c1BVkL4LC3HAI= k8s.io/cli-runtime v0.0.0-20190516231937-17bc0b7fcef5/go.mod h1:qWnH3/b8sp/l7EvlDh7ulDU3UWA4P4N1NFbEEP791tM= +k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= k8s.io/client-go v11.0.1-0.20190516230509-ae8359b20417+incompatible h1:bK03DJulJi9j05gwnXUufcs2j7h4M85YFvJ0dIlQ9k4= k8s.io/client-go v11.0.1-0.20190516230509-ae8359b20417+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= k8s.io/cloud-provider v0.0.0-20190516232619-2bf8e45c8454 h1:Xf+CNOo2Kx54V2Wlelg7N/J9NpiZTzhAlFxyzuiIrQ4= @@ -637,6 +691,8 @@ k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.2 h1:qvP/U6CcZ6qyi/qSHlJKdlAboCzo3mT0DAm0XAarpz4= k8s.io/klog v0.3.2/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c= +k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208 h1:5sW+fEHvlJI3Ngolx30CmubFulwH28DhKjGf70Xmtco= k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= k8s.io/kube-proxy v0.0.0-20190516232141-b2acb7b92548 h1:tEjlFuaZLa7iXPwiKomS6Aqck1KKAoslE0Q7EqvQQhw= @@ -655,9 +711,12 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20190124213536-fbb59629db34 h1:B1LAOfRqg2QUyCdzfjf46quTSYUTAK5OCwbh6pljHbM= mvdan.cc/unparam v0.0.0-20190124213536-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= +mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34 h1:duVSyluuJA+u0BnkcLR01smoLrGgDTfWt5c8ODYG8fU= mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= +sigs.k8s.io/kustomize/v3 v3.2.0 h1:EKcEubO29vCbigcMoNynfyZH+ANWkML2UHWibt1Do7o= +sigs.k8s.io/kustomize/v3 v3.2.0/go.mod h1:ztX4zYc/QIww3gSripwF7TBOarBTm5BvyAMem0kCzOE= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/pkg/document/bundle.go b/pkg/document/bundle.go new file mode 100644 index 000000000..3fbeaa757 --- /dev/null +++ b/pkg/document/bundle.go @@ -0,0 +1,255 @@ +package document + +import ( + "fmt" + "io" + + "sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/v3/k8sdeps/transformer" + "sigs.k8s.io/kustomize/v3/k8sdeps/validator" + "sigs.k8s.io/kustomize/v3/pkg/fs" + "sigs.k8s.io/kustomize/v3/pkg/gvk" + "sigs.k8s.io/kustomize/v3/pkg/loader" + "sigs.k8s.io/kustomize/v3/pkg/plugins" + "sigs.k8s.io/kustomize/v3/pkg/resmap" + "sigs.k8s.io/kustomize/v3/pkg/resource" + "sigs.k8s.io/kustomize/v3/pkg/target" + "sigs.k8s.io/kustomize/v3/pkg/types" + "sigs.k8s.io/yaml" +) + +// KustomizeBuildOptions contain the options for running a Kustomize build on a bundle +type KustomizeBuildOptions struct { + KustomizationPath string + OutputPath string + LoadRestrictor loader.LoadRestrictorFunc + OutOrder int +} + +// BundleFactory contains the objects within a bundle +type BundleFactory struct { + KustomizeBuildOptions + resmap.ResMap + fs.FileSystem +} + +// Bundle interface provides the specification for a bundle implementation +type Bundle interface { + Write(out io.Writer) error + GetKustomizeResourceMap() resmap.ResMap + SetKustomizeResourceMap(resmap.ResMap) error + GetKustomizeBuildOptions() KustomizeBuildOptions + SetKustomizeBuildOptions(KustomizeBuildOptions) error + SetFileSystem(fs.FileSystem) error + GetFileSystem() fs.FileSystem + Select(selector types.Selector) ([]Document, error) + GetByGvk(string, string, string) ([]Document, error) + GetByName(string) (Document, error) + GetByAnnotation(string) ([]Document, error) + GetByLabel(string) ([]Document, error) + GetAllDocuments() ([]Document, error) +} + +// NewBundle is a convenience function to create a new bundle +// Over time, it will evolve to support allowing more control +// for kustomize plugins +func NewBundle(fSys fs.FileSystem, kustomizePath string, outputPath string) (Bundle, error) { + + var options = KustomizeBuildOptions{ + KustomizationPath: kustomizePath, + OutputPath: outputPath, + LoadRestrictor: loader.RestrictionRootOnly, + OutOrder: 0, + } + + // init an empty bundle factory + var bundle Bundle = &BundleFactory{} + + // set the fs and build options we will use + bundle.SetFileSystem(fSys) + bundle.SetKustomizeBuildOptions(options) + + // boiler plate to allow us to run Kustomize build + uf := kunstruct.NewKunstructuredFactoryImpl() + pf := transformer.NewFactoryImpl() + rf := resmap.NewFactory(resource.NewFactory(uf), pf) + v := validator.NewKustValidator() + + pluginConfig := plugins.DefaultPluginConfig() + pl := plugins.NewLoader(pluginConfig, rf) + + ldr, err := loader.NewLoader( + bundle.GetKustomizeBuildOptions().LoadRestrictor, v, bundle.GetKustomizeBuildOptions().KustomizationPath, fSys) + if err != nil { + return bundle, err + } + defer ldr.Cleanup() + kt, err := target.NewKustTarget(ldr, rf, pf, pl) + if err != nil { + return bundle, err + } + + // build a resource map of kustomize rendered objects + m, err := kt.MakeCustomizedResMap() + bundle.SetKustomizeResourceMap(m) + if err != nil { + return bundle, err + } + + return bundle, nil + +} + +// GetKustomizeResourceMap returns a Kustomize Resource Map for this bundle +func (b *BundleFactory) GetKustomizeResourceMap() resmap.ResMap { + return b.ResMap +} + +// SetKustomizeResourceMap allows us to set the populated resource map for this bundle. In +// the future, it may modify it before saving it. +func (b *BundleFactory) SetKustomizeResourceMap(r resmap.ResMap) error { + b.ResMap = r + return nil +} + +// GetKustomizeBuildOptions returns the build options object used to generate the resource map +// for this bundle +func (b *BundleFactory) GetKustomizeBuildOptions() KustomizeBuildOptions { + return b.KustomizeBuildOptions +} + +// SetKustomizeBuildOptions sets the build options to be used for this bundle. In +// the future, it may perform some basic validations. +func (b *BundleFactory) SetKustomizeBuildOptions(k KustomizeBuildOptions) error { + b.KustomizeBuildOptions = k + return nil +} + +// SetFileSystem sets the filesystem that will be used by this bundle +func (b *BundleFactory) SetFileSystem(fSys fs.FileSystem) error { + b.FileSystem = fSys + return nil +} + +// GetFileSystem gets the filesystem that will be used by this bundle +func (b *BundleFactory) GetFileSystem() fs.FileSystem { + return b.FileSystem +} + +// GetAllDocuments returns all documents in this bundle +func (b *BundleFactory) GetAllDocuments() ([]Document, error) { + docSet := []Document{} + for _, res := range b.ResMap.Resources() { + // Construct Bundle document for each resource returned + doc, err := NewDocument(res) + if err != nil { + return docSet, err + } + docSet = append(docSet, doc) + } + return docSet, nil +} + +// GetByName finds a document by name, error if more than one document found +// or if no documents found +func (b *BundleFactory) GetByName(name string) (Document, error) { + resSet := []*resource.Resource{} + for _, res := range b.ResMap.Resources() { + if res.GetName() == name { + resSet = append(resSet, res) + } + } + // alanmeadows(TODO): improve this and other error potentials by + // by adding strongly typed errors + switch found := len(resSet); { + case found == 0: + return &DocumentFactory{}, fmt.Errorf("No documents found with name %s", name) + case found > 1: + return &DocumentFactory{}, fmt.Errorf("More than one document found with name %s", name) + default: + return NewDocument(resSet[0]) + } +} + +// Select offers a direct interface to pass a Kustomize Selector to the bundle +// returning Documents that match the criteria +func (b *BundleFactory) Select(selector types.Selector) ([]Document, error) { + + // use the kustomize select method + resources, err := b.ResMap.Select(selector) + if err != nil { + return []Document{}, err + } + + // Construct Bundle document for each resource returned + docSet := []Document{} + for _, res := range resources { + doc, err := NewDocument(res) + if err != nil { + return docSet, err + } + docSet = append(docSet, doc) + } + return docSet, err +} + +// GetByAnnotation is a convenience method to get documents for a particular annotation +func (b *BundleFactory) GetByAnnotation(annotation string) ([]Document, error) { + + // Construct kustomize annotation selector + selector := types.Selector{AnnotationSelector: annotation} + + // pass it to the selector + return b.Select(selector) + +} + +// GetByLabel is a convenience method to get documents for a particular label +func (b *BundleFactory) GetByLabel(label string) ([]Document, error) { + + // Construct kustomize annotation selector + selector := types.Selector{LabelSelector: label} + + // pass it to the selector + return b.Select(selector) + +} + +// GetByGvk is a convenience method to get documents for a particular Gvk tuple +func (b *BundleFactory) GetByGvk(group, version, kind string) ([]Document, error) { + + // Construct kustomize gvk object + g := gvk.Gvk{Group: group, Version: version, Kind: kind} + + // pass it to the selector + selector := types.Selector{Gvk: g} + return b.Select(selector) + +} + +// Write will write out the entire bundle resource map +func (b *BundleFactory) Write(out io.Writer) error { + for _, res := range b.ResMap.Resources() { + + yamlOut, err := yaml.Marshal(res.Map()) + if err != nil { + return err + } + // add separator for each document + _, err = out.Write([]byte("---\n")) + if err != nil { + return err + } + _, err = out.Write(yamlOut) + if err != nil { + return err + } + // add separator for each document + _, err = out.Write([]byte("...\n")) + if err != nil { + return err + } + + } + return nil +} diff --git a/pkg/document/bundle_test.go b/pkg/document/bundle_test.go new file mode 100644 index 000000000..98854f04f --- /dev/null +++ b/pkg/document/bundle_test.go @@ -0,0 +1,141 @@ +package document_test + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "sigs.k8s.io/kustomize/v3/pkg/gvk" + "sigs.k8s.io/kustomize/v3/pkg/types" + + "opendev.org/airship/airshipctl/pkg/document" + "opendev.org/airship/airshipctl/testutil" +) + +func TestNewBundle(t *testing.T) { + + fSys := testutil.SetupTestFs(t, "testdata") + bundle, err := document.NewBundle(fSys, "/", "/") + if err != nil { + t.Fatalf("Building Bundle Failed: %v", err) + } + + require := require.New(t) + require.NotNil(bundle) + +} + +func TestBundleDocumentFiltering(t *testing.T) { + + fSys := testutil.SetupTestFs(t, "testdata") + bundle, err := document.NewBundle(fSys, "/", "/") + if err != nil { + t.Fatalf("Building Bundle Failed: %v", err) + } + + assert := assert.New(t) + + t.Run("GetKustomizeResourceMap", func(t *testing.T) { + + r := bundle.GetKustomizeResourceMap() + + // ensure it is populated + assert.True(r.Size() > 0) + + }) + + t.Run("GetByGvk", func(t *testing.T) { + + docs, err := bundle.GetByGvk("apps", "v1", "Deployment") + if err != nil { + t.Fatalf("Error trying to GetGvk: %v", err) + } + + assert.Equal(len(docs), 3, "GetGvk returned the wrong number of resources") + + }) + + t.Run("GetByAnnotation", func(t *testing.T) { + + docs, err := bundle.GetByAnnotation("airshipit.org/clustertype=ephemeral") + if err != nil { + t.Fatalf("Error trying to GetByAnnotation: %v", err) + } + + assert.Equal(len(docs), 4, "GetByAnnotation returned wrong number of resources") + + }) + + t.Run("GetByLabel", func(t *testing.T) { + + docs, err := bundle.GetByLabel("app=workflow-controller") + if err != nil { + t.Fatalf("Error trying to GetByLabel: %v", err) + } + + assert.Equal(len(docs), 1, "GetByLabel returned wrong number of resources") + + }) + + t.Run("SelectGvk", func(t *testing.T) { + + // Select* tests test the Kustomize selector, which requires we build Kustomize + // selector objects which is useful for advanced searches that + // need to stack filters + g := gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"} + selector := types.Selector{Gvk: g} + docs, err := bundle.Select(selector) + if err != nil { + t.Fatalf("Error trying to select resources: %v", err) + } + assert.Equal(len(docs), 3, "SelectGvk returned wrong number of resources") + + }) + + t.Run("SelectAnnotations", func(t *testing.T) { + + // Find documents with a particular annotation, namely airshipit.org/clustertype=ephemeral + selector := types.Selector{AnnotationSelector: "airshipit.org/clustertype=ephemeral"} + docs, err := bundle.Select(selector) + if err != nil { + t.Fatalf("Error trying to select annotated resources: %v", err) + } + assert.Equal(len(docs), 4, "SelectAnnotations returned wrong number of resources") + + }) + + t.Run("SelectLabels", func(t *testing.T) { + + // Find documents with a particular label, namely app=workflow-controller + // note how this will only find resources labeled at the top most level (metadata.labels) + // and not spec templates with this label (spec.template.metadata.labels) + selector := types.Selector{LabelSelector: "app=workflow-controller"} + docs, err := bundle.Select(selector) + if err != nil { + t.Fatalf("Error trying to select labeled resources: %v", err) + } + assert.Equal(len(docs), 1, "SelectLabels returned wrong number of resources") + + }) + + t.Run("Write", func(t *testing.T) { + + // Ensure we can write out a bundle + // + // alanmeadows(TODO) improve validation what we write looks correct + var b bytes.Buffer + + err := bundle.Write(&b) + if err != nil { + t.Fatalf("Failed to write bundle out: %v", err) + } + + // b.String() will contain all kustomize built YAML + // so we for now we just search for an expected string + // obviously, this should be improved + assert.Contains(b.String(), "workflow-controller") + + }) + +} diff --git a/pkg/document/document.go b/pkg/document/document.go new file mode 100644 index 000000000..834a9c1c7 --- /dev/null +++ b/pkg/document/document.go @@ -0,0 +1,133 @@ +package document + +import ( + "sigs.k8s.io/kustomize/v3/pkg/resource" +) + +// DocumentFactory holds document data +type DocumentFactory struct { + resource.Resource +} + +// Document interface +type Document interface { + GetKustomizeResource() resource.Resource + SetKustomizeResource(*resource.Resource) error + AsYAML() ([]byte, error) + MarshalJSON() ([]byte, error) + GetName() string + GetKind() string + GetNamespace() string + GetString(path string) (string, error) + GetStringSlice(path string) ([]string, error) + GetBool(path string) (bool, error) + GetFloat64(path string) (float64, error) + GetInt64(path string) (int64, error) + GetSlice(path string) ([]interface{}, error) + GetStringMap(path string) (map[string]string, error) + GetMap(path string) (map[string]interface{}, error) +} + +// GetNamespace returns the namespace the resource thinks it's in. +func (d *DocumentFactory) GetNamespace() string { + namespace, _ := d.GetString("metadata.namespace") + // if err, namespace is empty, so no need to check. + return namespace +} + +// GetString returns the string value at path. +func (d *DocumentFactory) GetString(path string) (string, error) { + r := d.GetKustomizeResource() + return r.GetString(path) +} + +// GetStringSlice returns a string slice at path. +func (d *DocumentFactory) GetStringSlice(path string) ([]string, error) { + r := d.GetKustomizeResource() + return r.GetStringSlice(path) +} + +// GetBool returns a bool at path. +func (d *DocumentFactory) GetBool(path string) (bool, error) { + r := d.GetKustomizeResource() + return r.GetBool(path) +} + +// GetFloat64 returns a float64 at path. +func (d *DocumentFactory) GetFloat64(path string) (float64, error) { + r := d.GetKustomizeResource() + return r.GetFloat64(path) +} + +// GetInt64 returns an int64 at path. +func (d *DocumentFactory) GetInt64(path string) (int64, error) { + r := d.GetKustomizeResource() + return r.GetInt64(path) +} + +// GetSlice returns a slice at path. +func (d *DocumentFactory) GetSlice(path string) ([]interface{}, error) { + r := d.GetKustomizeResource() + return r.GetSlice(path) +} + +// GetStringMap returns a string map at path. +func (d *DocumentFactory) GetStringMap(path string) (map[string]string, error) { + r := d.GetKustomizeResource() + return r.GetStringMap(path) +} + +// GetMap returns a map at path. +func (d *DocumentFactory) GetMap(path string) (map[string]interface{}, error) { + r := d.GetKustomizeResource() + return r.GetMap(path) +} + +// AsYAML returns the document as a YAML byte stream. +func (d *DocumentFactory) AsYAML() ([]byte, error) { + r := d.GetKustomizeResource() + return r.AsYAML() +} + +// MarshalJSON returns the document as JSON. +func (d *DocumentFactory) MarshalJSON() ([]byte, error) { + r := d.GetKustomizeResource() + return r.MarshalJSON() +} + +// GetName returns the name: field from the document. +func (d *DocumentFactory) GetName() string { + r := d.GetKustomizeResource() + return r.GetName() +} + +// GetKind returns the Kind: field from the document. +func (d *DocumentFactory) GetKind() string { + r := d.GetKustomizeResource() + return r.GetKind() +} + +// GetKustomizeResource returns a Kustomize Resource object for this document. +func (d *DocumentFactory) GetKustomizeResource() resource.Resource { + return d.Resource +} + +// SetKustomizeResource sets a Kustomize Resource object for this document. +func (d *DocumentFactory) SetKustomizeResource(r *resource.Resource) error { + d.Resource = *r + return nil +} + +// NewDocument is a convenience method to construct a new Document. Although +// an error is unlikely at this time, this provides some future proofing for +// when we want more strict airship specific validation of documents getting +// created as this would be the front door for all Kustomize->Airship +// documents - e.g. in the future all documents require an airship +// annotation X +func NewDocument(r *resource.Resource) (Document, error) { + + var doc Document = &DocumentFactory{} + err := doc.SetKustomizeResource(r) + return doc, err + +} diff --git a/pkg/document/document_test.go b/pkg/document/document_test.go new file mode 100644 index 000000000..bd13fc466 --- /dev/null +++ b/pkg/document/document_test.go @@ -0,0 +1,133 @@ +package document_test + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "opendev.org/airship/airshipctl/pkg/document" + "opendev.org/airship/airshipctl/testutil" +) + +func TestDocument(t *testing.T) { + + // the easiest way to construct a bunch of documents + // is by manufacturing a bundle + // + // alanmeadows(TODO): at some point + // refactoring this so there isn't a reliance + // on a bundle might be useful + fSys := testutil.SetupTestFs(t, "testdata") + bundle, err := document.NewBundle(fSys, "/", "/") + if err != nil { + t.Fatalf("Unexpected error building bundle: %v", err) + } + + require := require.New(t) + assert := assert.New(t) + require.NotNil(bundle) + + t.Run("GetName", func(t *testing.T) { + + docs, err := bundle.GetAllDocuments() + if err != nil { + t.Fatalf("Unexpected error trying to GetAllDocuments: %v", err) + } + + nameList := []string{} + + for _, doc := range docs { + nameList = append(nameList, doc.GetName()) + } + + assert.Contains(nameList, "tiller-deploy", "Could not find expected name") + + }) + + t.Run("AsYAML", func(t *testing.T) { + + doc, err := bundle.GetByName("some-random-deployment-we-will-filter") + if err != nil { + t.Fatalf("Unexpected error trying to GetByName for AsYAML Test: %v", err) + } + + // see if we can marshal it while we're here for coverage + // as this is a dependency for AsYAML + json, err := doc.MarshalJSON() + assert.NotNil(json) + if err != nil { + t.Fatalf("Unexpected error trying to MarshalJSON(): %v", err) + } + + // get it as yaml + yaml, err := doc.AsYAML() + if err != nil { + t.Fatalf("Unexpected error trying to AsYAML(): %v", err) + } + + // convert the bytes into a string for comparison + // + // alanmeadows(NOTE): marshal can reorder things + // in the yaml, and does not return document beginning + // or end markers that may of been in the source so + // the FixtureInitiallyIgnored has been altered to + // look more or less how unmarshalling it would look + s := string(yaml) + fileData, err := fSys.ReadFile("/initially_ignored.yaml") + if err != nil { + t.Fatalf("Unexpected error reading initially_ignored.yaml file") + } + + // increase the chance of a match by removing any \n suffix on both actual + // and expected + assert.Equal(strings.TrimSuffix(s, "\n"), strings.TrimSuffix(string(fileData), "\n")) + + }) + + t.Run("GetString", func(t *testing.T) { + + doc, err := bundle.GetByName("some-random-deployment-we-will-filter") + if err != nil { + t.Fatalf("Unexpected error trying to GetByName for test: %v", err) + } + + appLabelMatch, err := doc.GetString("spec.selector.matchLabels.app") + if err != nil { + t.Fatalf("Unexpected error trying to GetString from document") + } + assert.Equal(appLabelMatch, "some-random-deployment-we-will-filter") + + }) + + t.Run("GetNamespace", func(t *testing.T) { + + doc, err := bundle.GetByName("some-random-deployment-we-will-filter") + if err != nil { + t.Fatalf("Unexpected error trying to GetByName for test: %v", err) + } + + assert.Equal("foobar", doc.GetNamespace()) + + }) + + t.Run("GetStringSlice", func(t *testing.T) { + + doc, err := bundle.GetByName("some-random-deployment-we-will-filter") + if err != nil { + t.Fatalf("Unexpected error trying to GetByName for test: %v", err) + } + s := make([]string, 1) + s[0] = "foobar" + + gotSlice, err := doc.GetStringSlice("spec.template.spec.containers[0].args") + if err != nil { + t.Fatalf("Unexpected error trying to GetStringSlice: %v", err) + } + + assert.Equal(s, gotSlice) + + }) + +} diff --git a/pkg/document/testdata/argo.yaml b/pkg/document/testdata/argo.yaml new file mode 100644 index 000000000..ff9384cce --- /dev/null +++ b/pkg/document/testdata/argo.yaml @@ -0,0 +1,290 @@ +--- +# This is an auto-generated file. DO NOT EDIT +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + airshipit.org/clustertype: target + name: workflows.argoproj.io +spec: + group: argoproj.io + names: + kind: Workflow + plural: workflows + shortNames: + - wf + scope: Namespaced + version: v1alpha1 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + airshipit.org/clustertype: target + name: argo-ui +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + airshipit.org/clustertype: target + name: argo +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + airshipit.org/clustertype: target + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" + name: argo-aggregate-to-admin +rules: +- apiGroups: + - argoproj.io + resources: + - workflows + - workflows/finalizers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + airshipit.org/clustertype: target + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + name: argo-aggregate-to-edit +rules: +- apiGroups: + - argoproj.io + resources: + - workflows + - workflows/finalizers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + airshipit.org/clustertype: target + labels: + rbac.authorization.k8s.io/aggregate-to-view: "true" + name: argo-aggregate-to-view +rules: +- apiGroups: + - argoproj.io + resources: + - workflows + - workflows/finalizers + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + airshipit.org/clustertype: target + name: argo-cluster-role +rules: +- apiGroups: + - "" + resources: + - pods + - pods/exec + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - watch + - list +- apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - create + - delete +- apiGroups: + - argoproj.io + resources: + - workflows + - workflows/finalizers + verbs: + - get + - list + - watch + - update + - patch + - delete +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + airshipit.org/clustertype: target + name: argo-ui-cluster-role +rules: +- apiGroups: + - "" + resources: + - pods + - pods/exec + - pods/log + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get +- apiGroups: + - argoproj.io + resources: + - workflows + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + annotations: + airshipit.org/clustertype: target + name: argo-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argo-cluster-role +subjects: +- kind: ServiceAccount + name: argo + namespace: argo +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + annotations: + airshipit.org/clustertype: target + name: argo-ui-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argo-ui-cluster-role +subjects: +- kind: ServiceAccount + name: argo-ui + namespace: argo +--- +apiVersion: v1 +kind: ConfigMap +metadata: + annotations: + airshipit.org/clustertype: target + name: workflow-controller-configmap +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + airshipit.org/clustertype: target + name: argo-ui +spec: + ports: + - port: 80 + targetPort: 8001 + selector: + app: argo-ui +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + airshipit.org/clustertype: target + name: argo-ui +spec: + selector: + matchLabels: + app: argo-ui + template: + metadata: + labels: + app: argo-ui + spec: + containers: + - env: + - name: ARGO_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: IN_CLUSTER + value: "true" + - name: ENABLE_WEB_CONSOLE + value: "false" + - name: BASE_HREF + value: / + image: argoproj/argoui:v2.3.0 + name: argo-ui + serviceAccountName: argo-ui +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + airshipit.org/clustertype: target + labels: + app: workflow-controller + name: workflow-controller +spec: + selector: + matchLabels: + app: workflow-controller + template: + metadata: + labels: + app: workflow-controller + spec: + containers: + - args: + - --configmap + - workflow-controller-configmap + - --executor-image + - argoproj/argoexec:v2.3.0 + command: + - workflow-controller + image: argoproj/workflow-controller:v2.3.0 + name: workflow-controller + serviceAccountName: argo +... \ No newline at end of file diff --git a/pkg/document/testdata/baremetal.yaml b/pkg/document/testdata/baremetal.yaml new file mode 100644 index 000000000..e5d8e5de5 --- /dev/null +++ b/pkg/document/testdata/baremetal.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: metal3.io/v1alpha1 +kind: BareMetalHost +metadata: + annotations: + airshipit.org/clustertype: ephemeral + name: master-0 +spec: + online: true + bootMACAddress: 00:3b:8b:0c:ec:8b + bmc: + address: ipmi://192.168.111.1:6230 + credentialsName: master-0-bmc-secret +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + airshipit.org/clustertype: ephemeral + name: master-0-bmc-secret +type: Opaque +data: + username: YWRtaW4= + password: cGFzc3dvcmQ= +--- +apiVersion: metal3.io/v1alpha1 +kind: BareMetalHost +metadata: + annotations: + airshipit.org/clustertype: target + name: master-1 +spec: + online: true + bootMACAddress: 01:3b:8b:0c:ec:8b + bmc: + address: ipmi://192.168.111.2:6230 + credentialsName: master-1-bmc-secret +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + airshipit.org/clustertype: target + name: master-1-bmc-secret +type: Opaque +data: + username: YWRtaW4= + password: cGFzc3dvcmQ= +... \ No newline at end of file diff --git a/pkg/document/testdata/initially_ignored.yaml b/pkg/document/testdata/initially_ignored.yaml new file mode 100644 index 000000000..05c2c142f --- /dev/null +++ b/pkg/document/testdata/initially_ignored.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + airshipit.org/clustertype: target + name: some-random-deployment-we-will-filter + namespace: foobar +spec: + selector: + matchLabels: + app: some-random-deployment-we-will-filter + serviceAccountName: something + template: + metadata: + labels: + app: some-random-deployment-we-will-filter + spec: + containers: + - args: + - foobar + command: + - somecommand + image: someimage + name: some-random-deployment-we-will-filter diff --git a/pkg/document/testdata/kustomization.yaml b/pkg/document/testdata/kustomization.yaml new file mode 100644 index 000000000..65bdb16bb --- /dev/null +++ b/pkg/document/testdata/kustomization.yaml @@ -0,0 +1,5 @@ +resources: + - baremetal.yaml + - tiller.yaml + - argo.yaml + - initially_ignored.yaml \ No newline at end of file diff --git a/pkg/document/testdata/tiller.yaml b/pkg/document/testdata/tiller.yaml new file mode 100644 index 000000000..bbcab1e16 --- /dev/null +++ b/pkg/document/testdata/tiller.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + annotations: + airshipit.org/clustertype: ephemeral + creationTimestamp: null + labels: + app: helm + name: tiller + name: tiller-deploy + namespace: kube-system +spec: + replicas: 1 + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: helm + name: tiller + spec: + automountServiceAccountToken: true + containers: + - env: + - name: TILLER_NAMESPACE + value: kube-system + - name: TILLER_HISTORY_MAX + value: "0" + image: gcr.io/kubernetes-helm/tiller:v2.12.3 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /liveness + port: 44135 + initialDelaySeconds: 1 + timeoutSeconds: 1 + name: tiller + ports: + - containerPort: 44134 + name: tiller + - containerPort: 44135 + name: http + readinessProbe: + httpGet: + path: /readiness + port: 44135 + initialDelaySeconds: 1 + timeoutSeconds: 1 + resources: {} +status: {} +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + airshipit.org/clustertype: ephemeral + creationTimestamp: null + labels: + app: helm + name: tiller + name: tiller-deploy + namespace: kube-system +spec: + ports: + - name: tiller + port: 44134 + targetPort: tiller + selector: + app: helm + name: tiller + type: ClusterIP +status: + loadBalancer: {} +... \ No newline at end of file diff --git a/testutil/testdatafs.go b/testutil/testdatafs.go new file mode 100644 index 000000000..571cf3678 --- /dev/null +++ b/testutil/testdatafs.go @@ -0,0 +1,38 @@ +package testutil + +import ( + "io/ioutil" + "path/filepath" + "testing" + + "sigs.k8s.io/kustomize/v3/pkg/fs" +) + +// SetupTestFs help manufacture a fake file system for testing purposes. It +// will iterate over the files in fixtureDir, which is a directory relative +// to the tests themselves, and will write each of those files (preserving +// names) to an in-memory file system and return that fs +func SetupTestFs(t *testing.T, fixtureDir string) fs.FileSystem { + + x := fs.MakeFakeFS() + + files, err := ioutil.ReadDir(fixtureDir) + if err != nil { + t.Fatalf("Unable to read fixture directory %s: %v", fixtureDir, err) + } + for _, file := range files { + fileName := file.Name() + filePath := filepath.Join(fixtureDir, fileName) + fileBytes, err := ioutil.ReadFile(filePath) + if err != nil { + t.Fatalf("Error reading fixture %s: %v", filePath, err) + } + // nolint: errcheck + err = x.WriteFile(filepath.Join("/", file.Name()), fileBytes) + if err != nil { + t.Fatalf("Error writing fixture %s: %v", filePath, err) + } + } + return x + +}