From 3bee2dde591d7eacc983b16d866e8b32812a206f Mon Sep 17 00:00:00 2001 From: sophieliu15 Date: Wed, 19 Feb 2020 21:36:11 -0500 Subject: [PATCH] Add a unit test for config_controller.go Add a unit test for config_controller.go to test the case that when a new type is added to HNCConfiguration singleton, the corresponding object reconciler can be created correctly. This PR also moves shared helper functions from each controller test files to a common file. Design doc: http://bit.ly/hnc-type-configuration Issue: #411 --- incubator/hnc/go.mod | 2 - incubator/hnc/go.sum | 130 -------- .../pkg/controllers/config_controller_test.go | 52 ++++ .../controllers/hierarchy_controller_test.go | 36 --- .../pkg/controllers/object_controller_test.go | 291 +++++++----------- incubator/hnc/pkg/controllers/suite_test.go | 7 + .../hnc/pkg/controllers/test_helpers_test.go | 186 +++++++++++ 7 files changed, 352 insertions(+), 352 deletions(-) create mode 100644 incubator/hnc/pkg/controllers/config_controller_test.go create mode 100644 incubator/hnc/pkg/controllers/test_helpers_test.go diff --git a/incubator/hnc/go.mod b/incubator/hnc/go.mod index 20a1a0334..8fc764a1c 100644 --- a/incubator/hnc/go.mod +++ b/incubator/hnc/go.mod @@ -3,7 +3,6 @@ module github.com/kubernetes-sigs/multi-tenancy/incubator/hnc go 1.12 require ( - contrib.go.opencensus.io/exporter/stackdriver v0.13.0 github.com/Azure/go-autorest/autorest v0.9.1 // indirect github.com/Azure/go-autorest/autorest/adal v0.6.0 // indirect github.com/emicklei/go-restful v2.10.0+incompatible // indirect @@ -17,7 +16,6 @@ require ( github.com/onsi/gomega v1.7.0 github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/spf13/cobra v0.0.5 - go.opencensus.io v0.22.3 k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d k8s.io/cli-runtime v0.0.0-20190314001948-2899ed30580f diff --git a/incubator/hnc/go.sum b/incubator/hnc/go.sum index ab6e99666..dbb201d72 100644 --- a/incubator/hnc/go.sum +++ b/incubator/hnc/go.sum @@ -1,15 +1,5 @@ cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -contrib.go.opencensus.io/exporter/stackdriver v0.13.0 h1:Jaz7WbqjtfoCPa1KbfisCX+P5aM3DizEY9pQMU0oAQo= -contrib.go.opencensus.io/exporter/stackdriver v0.13.0/go.mod h1:z2tyTZtPmQ2HvWH4cOmVDgtY+1lomfKdbLnkJvZdc8c= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.1 h1:JB7Mqhna/7J8gZfVHjxDSTLSD6ciz2YgSMb/4qLXTtY= github.com/Azure/go-autorest/autorest v0.9.1/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= @@ -28,19 +18,13 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aws/aws-sdk-go v1.23.20 h1:2CBuL21P0yKdZN5urf2NxKa1ha8fhnY+A3pBCHFeZoA= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -81,34 +65,17 @@ github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7 h1:u4bArs140e9+AfE52mFHOXVFnOSBJBRlzTHrOPLOIhE= github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/gophercloud/gophercloud v0.4.0 h1:4iXQnHF7LKOl7ncQsRibnUmfx/unxT3rLAniYRB8kQQ= @@ -117,9 +84,6 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47 h1:UnszMmmmm5vLwWzDjTFVIkfhvWF1NdrmChl8L2NUDCw= github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -127,13 +91,10 @@ github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -187,7 +148,6 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrO github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 h1:agujYaXJSxSo18YNX3jzl+4G6Bstwt+kqv47GS12uL0= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -206,14 +166,8 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH 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/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= -go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= @@ -227,51 +181,21 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 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/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A= @@ -280,76 +204,28 @@ golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 h1:+DCIGbF/swA92ohVg0//6X2IVY3KZs6p9mix0ziNYJM= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190501045030-23463209683d/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SGrZkZixxWpwNCDiwJfh88= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0 h1:7tmAxx3oKE98VMZ+SBZzvYYWRQ9HODBxmC8mXUsraSQ= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= 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= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -362,11 +238,6 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22 h1:0efs3hwEZhFKsCoP8l6dDB1AZWMgnEl3yWXWRZTOaEA= gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b h1:aBGgKJUM9Hk/3AE8WaZIApnTxG35kbuQba2w+SXqezo= k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8 h1:q1Qvjzs/iEdXF6A1a8H3AKVFDzJNcJn3nXMs6R6qFtA= @@ -384,7 +255,6 @@ k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c h1:3KSCztE7gPitlZmWbNwue/ k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5 h1:VBM/0P5TWxwk+Nw6Z+lAw3DKgO76g90ETOiA6rfLV1Y= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= sigs.k8s.io/controller-runtime v0.2.2 h1:JT/vJJhUjjL9NZNwnm8AXmqCBUXSCFKmTaNjwDi28N0= sigs.k8s.io/controller-runtime v0.2.2/go.mod h1:9dyohw3ZtoXQuV1e766PHUn+cmrRCIcBh6XIMFNMZ+I= sigs.k8s.io/controller-tools v0.2.1 h1:HoCik83vXOpPi7KSJWdPRmiGntyOzK0v0BTV4U+pl8o= diff --git a/incubator/hnc/pkg/controllers/config_controller_test.go b/incubator/hnc/pkg/controllers/config_controller_test.go new file mode 100644 index 000000000..d85f4c21b --- /dev/null +++ b/incubator/hnc/pkg/controllers/config_controller_test.go @@ -0,0 +1,52 @@ +package controllers_test + +import ( + "context" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("HNCConfiguration", func() { + ctx := context.Background() + + var ( + fooName string + barName string + ) + + BeforeEach(func() { + fooName = createNS(ctx, "foo") + barName = createNS(ctx, "bar") + }) + + AfterEach(func() { + // Change current singleton back to the default value. + Eventually(func() error { + c := getHNCConfig(ctx) + return resetHNCConfigToDefault(ctx, c) + }).Should(Succeed()) + }) + + It("should propagate objects whose types have been added to HNCConfiguration", func() { + setParent(ctx, barName, fooName) + makeSecret(ctx, fooName, "foo-sec") + + // Wait 1 second to give "foo-sec" a chance to be propagated to bar, if it can be propagated. + time.Sleep(1 * time.Second) + // Foo should have "foo-sec" since we created it there. + Eventually(hasSecret(ctx, fooName, "foo-sec")).Should(BeTrue()) + // "foo-sec" is not propagated to bar because Secret hasn't been configured in HNCConfiguration. + Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeFalse()) + + Eventually(func() error { + c := getHNCConfig(ctx) + return addSecretToHNCConfig(ctx, c) + }).Should(Succeed()) + + // "foo-sec" should now be propagated from foo to bar. + Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) + Expect(secretInheritedFrom(ctx, barName, "foo-sec")).Should(Equal(fooName)) + }) +}) diff --git a/incubator/hnc/pkg/controllers/hierarchy_controller_test.go b/incubator/hnc/pkg/controllers/hierarchy_controller_test.go index 8ab4514c5..083bdb29a 100644 --- a/incubator/hnc/pkg/controllers/hierarchy_controller_test.go +++ b/incubator/hnc/pkg/controllers/hierarchy_controller_test.go @@ -3,7 +3,6 @@ package controllers_test import ( "context" "fmt" - "math/rand" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -386,41 +385,6 @@ func updateHierarchy(ctx context.Context, h *api.HierarchyConfiguration) { } } -// createNSName generates random namespace names. Namespaces are never deleted in test-env because -// the building Namespace controller (which finalizes namespaces) doesn't run; I searched Github and -// found that everyone who was deleting namespaces was *also* very intentionally generating random -// names, so I guess this problem is widespread. -func createNSName(prefix string) string { - suffix := make([]byte, 10) - rand.Read(suffix) - return fmt.Sprintf("%s-%x", prefix, suffix) -} - -// createNSWithLabel has similar function to createNS with label as additional parameter -func createNSWithLabel(ctx context.Context, prefix string, label map[string]string) string { - nm := createNSName(prefix) - - // Create the namespace - ns := &corev1.Namespace{} - ns.SetLabels(label) - ns.Name = nm - Expect(k8sClient.Create(ctx, ns)).Should(Succeed()) - return nm -} - -// createNS is a convenience function to create a namespace and wait for its singleton to be -// created. It's used in other tests in this package, but basically duplicates the code in this test -// (it didn't originally). TODO: refactor. -func createNS(ctx context.Context, prefix string) string { - nm := createNSName(prefix) - - // Create the namespace - ns := &corev1.Namespace{} - ns.Name = nm - Expect(k8sClient.Create(ctx, ns)).Should(Succeed()) - return nm -} - func getLabel(ctx context.Context, from, label string) func() string { return func() string { ns := getNamespace(ctx, from) diff --git a/incubator/hnc/pkg/controllers/object_controller_test.go b/incubator/hnc/pkg/controllers/object_controller_test.go index 8dd4939ca..5e06921e2 100644 --- a/incubator/hnc/pkg/controllers/object_controller_test.go +++ b/incubator/hnc/pkg/controllers/object_controller_test.go @@ -7,19 +7,16 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" api "github.com/kubernetes-sigs/multi-tenancy/incubator/hnc/api/v1alpha1" - "github.com/kubernetes-sigs/multi-tenancy/incubator/hnc/pkg/config" ) var _ = Describe("Secret", func() { ctx := context.Background() - // Setup HNCConfiguration. - hncConfig := newHNCConfig() - var ( fooName string barName string @@ -27,97 +24,94 @@ var _ = Describe("Secret", func() { ) BeforeEach(func() { - // Add secret to HNCConfiguration so that an ObjectReconciler will be created for secret. - addSecretToHNCConfig(ctx, hncConfig) - fooName = createNS(ctx, "foo") barName = createNS(ctx, "bar") bazName = createNS(ctx, "baz") // Give them each a secret - makeSecret(ctx, fooName, "foo-sec") - makeSecret(ctx, barName, "bar-sec") - makeSecret(ctx, bazName, "baz-sec") + makeRole(ctx, fooName, "foo-role") + makeRole(ctx, barName, "bar-role") + makeRole(ctx, bazName, "baz-role") }) It("should be copied to descendents", func() { setParent(ctx, barName, fooName) setParent(ctx, bazName, barName) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, barName, "foo-sec")).Should(Equal(fooName)) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, barName, "foo-role")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "foo-sec")).Should(Equal(fooName)) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "foo-role")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, bazName, "bar-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "bar-sec")).Should(Equal(barName)) + Eventually(hasRole(ctx, bazName, "bar-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "bar-role")).Should(Equal(barName)) }) It("should be removed if the hierarchy changes", func() { setParent(ctx, barName, fooName) setParent(ctx, bazName, barName) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) - Eventually(hasSecret(ctx, bazName, "bar-sec")).Should(BeTrue()) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) + Eventually(hasRole(ctx, bazName, "bar-role")).Should(BeTrue()) setParent(ctx, bazName, fooName) - Eventually(hasSecret(ctx, bazName, "bar-sec")).Should(BeFalse()) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) + Eventually(hasRole(ctx, bazName, "bar-role")).Should(BeFalse()) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) setParent(ctx, bazName, "") - Eventually(hasSecret(ctx, bazName, "bar-sec")).Should(BeFalse()) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeFalse()) + Eventually(hasRole(ctx, bazName, "bar-role")).Should(BeFalse()) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeFalse()) }) It("should not be propagated if modified", func() { - // Set tree as bar -> foo and make sure the first-time propagation of foo-sec - // is finished before modifying the foo-sec in bar namespace + // Set tree as bar -> foo and make sure the first-time propagation of foo-role + // is finished before modifying the foo-role in bar namespace setParent(ctx, barName, fooName) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeTrue()) // Wait 1 second to make sure all enqueued fooName hiers are successfully reconciled // in case the manual modification is overridden by the unfinished propagation. time.Sleep(1 * time.Second) - modifySecret(ctx, barName, "foo-sec") + modifyRole(ctx, barName, "foo-role") // Set as parent. Give the controller a chance to copy the objects and make // sure that at least the correct one was copied. This gives us more confidence // that if the other one *isn't* copied, this is because we decided not to, and // not that we just haven't gotten to it yet. setParent(ctx, bazName, barName) - Eventually(hasSecret(ctx, bazName, "bar-sec")).Should(BeTrue()) + Eventually(hasRole(ctx, bazName, "bar-role")).Should(BeTrue()) // Make sure the bad one got overwritte. - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) }) It("should be removed if the source no longer exists", func() { setParent(ctx, barName, fooName) setParent(ctx, bazName, barName) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeTrue()) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) - removeSecret(ctx, fooName, "foo-sec") + removeRole(ctx, fooName, "foo-role") // Wait 1 second to make sure the propagated objects are removed. time.Sleep(1 * time.Second) - Eventually(hasSecret(ctx, fooName, "foo-sec")).Should(BeFalse()) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeFalse()) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeFalse()) + Eventually(hasRole(ctx, fooName, "foo-role")).Should(BeFalse()) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeFalse()) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeFalse()) }) It("should overwrite the propagated ones if the source is updated", func() { setParent(ctx, barName, fooName) setParent(ctx, bazName, barName) - Eventually(isModified(ctx, fooName, "foo-sec")).Should(BeFalse()) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) - Eventually(isModified(ctx, barName, "foo-sec")).Should(BeFalse()) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) - Eventually(isModified(ctx, bazName, "foo-sec")).Should(BeFalse()) + Eventually(isModified(ctx, fooName, "foo-role")).Should(BeFalse()) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeTrue()) + Eventually(isModified(ctx, barName, "foo-role")).Should(BeFalse()) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) + Eventually(isModified(ctx, bazName, "foo-role")).Should(BeFalse()) - modifySecret(ctx, fooName, "foo-sec") + modifyRole(ctx, fooName, "foo-role") // Wait 1 second to make sure the updated source get propagated. time.Sleep(1 * time.Second) - Eventually(isModified(ctx, fooName, "foo-sec")).Should(BeTrue()) - Eventually(isModified(ctx, barName, "foo-sec")).Should(BeTrue()) - Eventually(isModified(ctx, bazName, "foo-sec")).Should(BeTrue()) + Eventually(isModified(ctx, fooName, "foo-role")).Should(BeTrue()) + Eventually(isModified(ctx, barName, "foo-role")).Should(BeTrue()) + Eventually(isModified(ctx, bazName, "foo-role")).Should(BeTrue()) }) It("shouldn't propagate/delete if the namespace has Crit condition", func() { @@ -125,13 +119,13 @@ var _ = Describe("Secret", func() { setParent(ctx, barName, fooName) setParent(ctx, bazName, barName) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, barName, "foo-sec")).Should(Equal(fooName)) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, barName, "foo-role")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "foo-sec")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, bazName, "bar-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "bar-sec")).Should(Equal(barName)) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "foo-role")).Should(Equal(fooName)) + Eventually(hasRole(ctx, bazName, "bar-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "bar-role")).Should(Equal(barName)) // Set foo's parent to a non-existent namespace. brumpfName := createNSName("brumpf") @@ -142,25 +136,25 @@ var _ = Describe("Secret", func() { Eventually(hasCondition(ctx, barName, api.CritAncestor)).Should(Equal(true)) Eventually(hasCondition(ctx, bazName, api.CritAncestor)).Should(Equal(true)) - // Set baz's parent to foo and add a new sec in foo. + // Set baz's parent to foo and add a new role in foo. setParent(ctx, bazName, fooName) - makeSecret(ctx, fooName, "foo-sec-2") + makeRole(ctx, fooName, "foo-role-2") // Wait 1 second to make sure any potential actions are done. time.Sleep(1 * time.Second) - // Since the sync is frozen, baz should still have bar-sec (no deleting). - Eventually(hasSecret(ctx, bazName, "bar-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "bar-sec")).Should(Equal(barName)) - // baz and bar shouldn't have foo-sec-2 (no propagating). - Eventually(hasSecret(ctx, bazName, "foo-sec-2")).Should(BeFalse()) - Eventually(hasSecret(ctx, barName, "foo-sec-2")).Should(BeFalse()) + // Since the sync is frozen, baz should still have bar-role (no deleting). + Eventually(hasRole(ctx, bazName, "bar-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "bar-role")).Should(Equal(barName)) + // baz and bar shouldn't have foo-role-2 (no propagating). + Eventually(hasRole(ctx, bazName, "foo-role-2")).Should(BeFalse()) + Eventually(hasRole(ctx, barName, "foo-role-2")).Should(BeFalse()) // Create the missing parent namespace with one object. brumpfNS := &corev1.Namespace{} brumpfNS.Name = brumpfName Expect(k8sClient.Create(ctx, brumpfNS)).Should(Succeed()) - makeSecret(ctx, brumpfName, "brumpf-sec") + makeRole(ctx, brumpfName, "brumpf-role") // The Crit conditions should be gone. Eventually(hasCondition(ctx, fooName, api.CritParentMissing)).Should(Equal(false)) @@ -168,107 +162,57 @@ var _ = Describe("Secret", func() { Eventually(hasCondition(ctx, bazName, api.CritAncestor)).Should(Equal(false)) // Everything should be up to date after the Crit conditions are gone. - Eventually(hasSecret(ctx, fooName, "brumpf-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, fooName, "brumpf-sec")).Should(Equal(brumpfName)) - - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, barName, "foo-sec")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, barName, "foo-sec-2")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, barName, "foo-sec-2")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, barName, "brumpf-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, barName, "brumpf-sec")).Should(Equal(brumpfName)) - - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "foo-sec")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, bazName, "foo-sec-2")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "foo-sec-2")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, bazName, "brumpf-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "brumpf-sec")).Should(Equal(brumpfName)) - - Eventually(hasSecret(ctx, bazName, "bar-sec")).Should(BeFalse()) + Eventually(hasRole(ctx, fooName, "brumpf-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, fooName, "brumpf-role")).Should(Equal(brumpfName)) + + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, barName, "foo-role")).Should(Equal(fooName)) + Eventually(hasRole(ctx, barName, "foo-role-2")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, barName, "foo-role-2")).Should(Equal(fooName)) + Eventually(hasRole(ctx, barName, "brumpf-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, barName, "brumpf-role")).Should(Equal(brumpfName)) + + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "foo-role")).Should(Equal(fooName)) + Eventually(hasRole(ctx, bazName, "foo-role-2")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "foo-role-2")).Should(Equal(fooName)) + Eventually(hasRole(ctx, bazName, "brumpf-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "brumpf-role")).Should(Equal(brumpfName)) + + Eventually(hasRole(ctx, bazName, "bar-role")).Should(BeFalse()) }) It("should set conditions if it's excluded from being propagated, and clear them if it's fixed", func() { // Set tree as baz -> bar -> foo(root) and make sure the secret gets propagated. setParent(ctx, barName, fooName) setParent(ctx, bazName, barName) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, barName, "foo-sec")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "foo-sec")).Should(Equal(fooName)) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, barName, "foo-role")).Should(Equal(fooName)) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "foo-role")).Should(Equal(fooName)) // Make the secret unpropagateable and verify that it disappears. - setFinalizer(ctx, fooName, "foo-sec", true) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeFalse()) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeFalse()) + setFinalizer(ctx, fooName, "foo-role", true) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeFalse()) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeFalse()) // Observe the condition on the source namespace want := &api.Condition{ Code: api.CannotPropagate, - Affects: []api.AffectedObject{{Version: "v1", Kind: "Secret", Namespace: fooName, Name: "foo-sec"}}, + Affects: []api.AffectedObject{{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "Role", Namespace: fooName, Name: "foo-role"}}, } Eventually(getCondition(ctx, fooName, api.CannotPropagate)).Should(Equal(want)) // Fix the problem and verify that the condition vanishes and the secret is propagated again - setFinalizer(ctx, fooName, "foo-sec", false) + setFinalizer(ctx, fooName, "foo-role", false) Eventually(hasCondition(ctx, fooName, api.CannotPropagate)).Should(Equal(false)) - Eventually(hasSecret(ctx, barName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, barName, "foo-sec")).Should(Equal(fooName)) - Eventually(hasSecret(ctx, bazName, "foo-sec")).Should(BeTrue()) - Expect(secretInheritedFrom(ctx, bazName, "foo-sec")).Should(Equal(fooName)) + Eventually(hasRole(ctx, barName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, barName, "foo-role")).Should(Equal(fooName)) + Eventually(hasRole(ctx, bazName, "foo-role")).Should(BeTrue()) + Expect(roleInheritedFrom(ctx, bazName, "foo-role")).Should(Equal(fooName)) }) }) -func makeSecret(ctx context.Context, nsName, secretName string) { - sec := &corev1.Secret{} - sec.Name = secretName - sec.Namespace = nsName - ExpectWithOffset(1, k8sClient.Create(ctx, sec)).Should(Succeed()) -} - -func hasSecret(ctx context.Context, nsName, secretName string) func() bool { - // `Eventually` only works with a fn that doesn't take any args - return func() bool { - nnm := types.NamespacedName{Namespace: nsName, Name: secretName} - sec := &corev1.Secret{} - err := k8sClient.Get(ctx, nnm, sec) - return err == nil - } -} - -func secretInheritedFrom(ctx context.Context, nsName, secretName string) string { - nnm := types.NamespacedName{Namespace: nsName, Name: secretName} - sec := &corev1.Secret{} - if err := k8sClient.Get(ctx, nnm, sec); err != nil { - // should have been caught above - return err.Error() - } - if sec.ObjectMeta.Labels == nil { - return "" - } - lif, _ := sec.ObjectMeta.Labels["hnc.x-k8s.io/inheritedFrom"] - return lif -} - -func setParent(ctx context.Context, nm string, pnm string) { - hier := newOrGetHierarchy(ctx, nm) - oldPNM := hier.Spec.Parent - hier.Spec.Parent = pnm - updateHierarchy(ctx, hier) - if oldPNM != "" { - EventuallyWithOffset(1, func() []string { - pHier := getHierarchyWithOffset(1, ctx, oldPNM) - return pHier.Status.Children - }).ShouldNot(ContainElement(nm)) - } - if pnm != "" { - EventuallyWithOffset(1, func() []string { - pHier := getHierarchyWithOffset(1, ctx, pnm) - return pHier.Status.Children - }).Should(ContainElement(nm)) - } -} - func newOrGetHierarchy(ctx context.Context, nm string) *api.HierarchyConfiguration { hier := &api.HierarchyConfiguration{} hier.ObjectMeta.Namespace = nm @@ -280,66 +224,45 @@ func newOrGetHierarchy(ctx context.Context, nm string) *api.HierarchyConfigurati return hier } -func modifySecret(ctx context.Context, nsName, secretName string) { - nnm := types.NamespacedName{Namespace: nsName, Name: secretName} - sec := &corev1.Secret{} - ExpectWithOffset(1, k8sClient.Get(ctx, nnm, sec)).Should(Succeed()) +func modifyRole(ctx context.Context, nsName, roleName string) { + nnm := types.NamespacedName{Namespace: nsName, Name: roleName} + role := &v1.Role{} + ExpectWithOffset(1, k8sClient.Get(ctx, nnm, role)).Should(Succeed()) - labels := sec.GetLabels() + labels := role.GetLabels() if labels == nil { labels = map[string]string{} } labels["modify"] = "make-a-change" - sec.SetLabels(labels) - ExpectWithOffset(1, k8sClient.Update(ctx, sec)).Should(Succeed()) + role.SetLabels(labels) + ExpectWithOffset(1, k8sClient.Update(ctx, role)).Should(Succeed()) } -func setFinalizer(ctx context.Context, nsName, secretName string, set bool) { - nnm := types.NamespacedName{Namespace: nsName, Name: secretName} - sec := &corev1.Secret{} - ExpectWithOffset(1, k8sClient.Get(ctx, nnm, sec)).Should(Succeed()) +func setFinalizer(ctx context.Context, nsName, roleName string, set bool) { + nnm := types.NamespacedName{Namespace: nsName, Name: roleName} + role := &v1.Role{} + ExpectWithOffset(1, k8sClient.Get(ctx, nnm, role)).Should(Succeed()) if set { - sec.ObjectMeta.Finalizers = []string{"example.com/foo"} + role.ObjectMeta.Finalizers = []string{"example.com/foo"} } else { - sec.ObjectMeta.Finalizers = nil + role.ObjectMeta.Finalizers = nil } - ExpectWithOffset(1, k8sClient.Update(ctx, sec)).Should(Succeed()) + ExpectWithOffset(1, k8sClient.Update(ctx, role)).Should(Succeed()) } -func isModified(ctx context.Context, nsName, secretName string) bool { - nnm := types.NamespacedName{Namespace: nsName, Name: secretName} - sec := &corev1.Secret{} - ExpectWithOffset(1, k8sClient.Get(ctx, nnm, sec)).Should(Succeed()) +func isModified(ctx context.Context, nsName, roleName string) bool { + nnm := types.NamespacedName{Namespace: nsName, Name: roleName} + role := &v1.Role{} + ExpectWithOffset(1, k8sClient.Get(ctx, nnm, role)).Should(Succeed()) - labels := sec.GetLabels() + labels := role.GetLabels() _, ok := labels["modify"] return ok } -func removeSecret(ctx context.Context, nsName, secretName string) { - sec := &corev1.Secret{} - sec.Name = secretName - sec.Namespace = nsName - ExpectWithOffset(1, k8sClient.Delete(ctx, sec)).Should(Succeed()) -} - -func newHNCConfig() *api.HNCConfiguration { - hncConfig := &api.HNCConfiguration{} - hncConfig.ObjectMeta.Name = api.HNCConfigSingleton - hncConfig.Spec = config.GetDefaultConfigSpec() - return hncConfig -} - -func updateHNCConfig(ctx context.Context, c *api.HNCConfiguration) { - if c.CreationTimestamp.IsZero() { - ExpectWithOffset(1, k8sClient.Create(ctx, c)).Should(Succeed()) - } else { - ExpectWithOffset(1, k8sClient.Update(ctx, c)).Should(Succeed()) - } -} - -func addSecretToHNCConfig(ctx context.Context, c *api.HNCConfiguration) { - secSpec := api.TypeSynchronizationSpec{APIVersion: "v1", Kind: "Secret", Mode: api.Propagate} - c.Spec.Types = append(c.Spec.Types, secSpec) - updateHNCConfig(ctx, c) +func removeRole(ctx context.Context, nsName, roleName string) { + role := &v1.Role{} + role.Name = roleName + role.Namespace = nsName + ExpectWithOffset(1, k8sClient.Delete(ctx, role)).Should(Succeed()) } diff --git a/incubator/hnc/pkg/controllers/suite_test.go b/incubator/hnc/pkg/controllers/suite_test.go index b8a2d5a04..2abf89d43 100644 --- a/incubator/hnc/pkg/controllers/suite_test.go +++ b/incubator/hnc/pkg/controllers/suite_test.go @@ -16,6 +16,7 @@ limitations under the License. package controllers_test import ( + "context" "path/filepath" "testing" "time" @@ -90,6 +91,12 @@ var _ = BeforeSuite(func(done Done) { k8sClient = k8sManager.GetClient() Expect(k8sClient).ToNot(BeNil()) + // Setup HNCConfiguration object here because it is a cluster-wide singleton shared by all reconcilers. + hncConfig := newHNCConfig() + Expect(hncConfig).ToNot(BeNil()) + ctx := context.Background() + updateHNCConfig(ctx, hncConfig) + go func() { err = k8sManager.Start(ctrl.SetupSignalHandler()) Expect(err).ToNot(HaveOccurred()) diff --git a/incubator/hnc/pkg/controllers/test_helpers_test.go b/incubator/hnc/pkg/controllers/test_helpers_test.go new file mode 100644 index 000000000..166897e8c --- /dev/null +++ b/incubator/hnc/pkg/controllers/test_helpers_test.go @@ -0,0 +1,186 @@ +package controllers_test + +import ( + "context" + "crypto/rand" + "fmt" + + "github.com/kubernetes-sigs/multi-tenancy/incubator/hnc/pkg/config" + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + api "github.com/kubernetes-sigs/multi-tenancy/incubator/hnc/api/v1alpha1" +) + +func setParent(ctx context.Context, nm string, pnm string) { + hier := newOrGetHierarchy(ctx, nm) + oldPNM := hier.Spec.Parent + hier.Spec.Parent = pnm + updateHierarchy(ctx, hier) + if oldPNM != "" { + EventuallyWithOffset(1, func() []string { + pHier := getHierarchyWithOffset(1, ctx, oldPNM) + return pHier.Status.Children + }).ShouldNot(ContainElement(nm)) + } + if pnm != "" { + EventuallyWithOffset(1, func() []string { + pHier := getHierarchyWithOffset(1, ctx, pnm) + return pHier.Status.Children + }).Should(ContainElement(nm)) + } +} + +// createNSName generates random namespace names. Namespaces are never deleted in test-env because +// the building Namespace controller (which finalizes namespaces) doesn't run; I searched Github and +// found that everyone who was deleting namespaces was *also* very intentionally generating random +// names, so I guess this problem is widespread. +func createNSName(prefix string) string { + suffix := make([]byte, 10) + rand.Read(suffix) + return fmt.Sprintf("%s-%x", prefix, suffix) +} + +func newHNCConfig() *api.HNCConfiguration { + hncConfig := &api.HNCConfiguration{} + hncConfig.ObjectMeta.Name = api.HNCConfigSingleton + hncConfig.Spec = config.GetDefaultConfigSpec() + return hncConfig +} + +func updateHNCConfig(ctx context.Context, c *api.HNCConfiguration) error { + if c.CreationTimestamp.IsZero() { + return k8sClient.Create(ctx, c) + } else { + return k8sClient.Update(ctx, c) + } +} + +func getHNCConfig(ctx context.Context) *api.HNCConfiguration { + return getHNCConfigWithOffset(1, ctx) +} + +func getHNCConfigWithOffset(offset int, ctx context.Context) *api.HNCConfiguration { + snm := types.NamespacedName{Name: api.HNCConfigSingleton} + config := &api.HNCConfiguration{} + EventuallyWithOffset(offset+1, func() error { + return k8sClient.Get(ctx, snm, config) + }).Should(Succeed()) + return config +} + +func resetHNCConfigToDefault(ctx context.Context, c *api.HNCConfiguration) error { + c.Spec = config.GetDefaultConfigSpec() + return k8sClient.Update(ctx, c) +} + +// createNSWithLabel has similar function to createNS with label as additional parameter +func createNSWithLabel(ctx context.Context, prefix string, label map[string]string) string { + nm := createNSName(prefix) + + // Create the namespace + ns := &corev1.Namespace{} + ns.SetLabels(label) + ns.Name = nm + Expect(k8sClient.Create(ctx, ns)).Should(Succeed()) + return nm +} + +// createNS is a convenience function to create a namespace and wait for its singleton to be +// created. It's used in other tests in this package, but basically duplicates the code in this test +// (it didn't originally). TODO: refactor. +func createNS(ctx context.Context, prefix string) string { + nm := createNSName(prefix) + + // Create the namespace + ns := &corev1.Namespace{} + ns.Name = nm + Expect(k8sClient.Create(ctx, ns)).Should(Succeed()) + return nm +} + +func addSecretToHNCConfig(ctx context.Context, c *api.HNCConfiguration) error { + secSpec := api.TypeSynchronizationSpec{APIVersion: "v1", Kind: "Secret", Mode: api.Propagate} + c.Spec.Types = append(c.Spec.Types, secSpec) + return updateHNCConfig(ctx, c) +} + +func makeSecret(ctx context.Context, nsName, secretName string) { + sec := &corev1.Secret{} + sec.Name = secretName + sec.Namespace = nsName + ExpectWithOffset(1, k8sClient.Create(ctx, sec)).Should(Succeed()) +} + +func hasSecret(ctx context.Context, nsName, secretName string) func() bool { + // `Eventually` only works with a fn that doesn't take any args + return func() bool { + nnm := types.NamespacedName{Namespace: nsName, Name: secretName} + sec := &corev1.Secret{} + err := k8sClient.Get(ctx, nnm, sec) + return err == nil + } +} + +func secretInheritedFrom(ctx context.Context, nsName, secretName string) string { + nnm := types.NamespacedName{Namespace: nsName, Name: secretName} + sec := &corev1.Secret{} + if err := k8sClient.Get(ctx, nnm, sec); err != nil { + // should have been caught above + return err.Error() + } + if sec.ObjectMeta.Labels == nil { + return "" + } + lif, _ := sec.ObjectMeta.Labels["hnc.x-k8s.io/inheritedFrom"] + return lif +} + +func makeRole(ctx context.Context, nsName, roleName string) { + role := &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Namespace: nsName, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Role", + APIVersion: "rbac.authorization.k8s.io/v1", + }, + Rules: []v1.PolicyRule{ + // Allow the users to read all secrets, namespaces and configmaps. + { + APIGroups: []string{""}, + Resources: []string{"secrets", "namespaces", "configmaps"}, + Verbs: []string{"get", "watch", "list"}, + }, + }, + } + ExpectWithOffset(1, k8sClient.Create(ctx, role)).Should(Succeed()) +} + +func hasRole(ctx context.Context, nsName, roleName string) func() bool { + // `Eventually` only works with a fn that doesn't take any args + return func() bool { + nnm := types.NamespacedName{Namespace: nsName, Name: roleName} + role := &v1.Role{} + err := k8sClient.Get(ctx, nnm, role) + return err == nil + } +} + +func roleInheritedFrom(ctx context.Context, nsName, roleName string) string { + nnm := types.NamespacedName{Namespace: nsName, Name: roleName} + role := &v1.Role{} + if err := k8sClient.Get(ctx, nnm, role); err != nil { + // should have been caught above + return err.Error() + } + if role.ObjectMeta.Labels == nil { + return "" + } + lif, _ := role.ObjectMeta.Labels["hnc.x-k8s.io/inheritedFrom"] + return lif +}