From 2a56f8336c7618cb04c3255590817226aecdd05b Mon Sep 17 00:00:00 2001 From: Zhiwei Yin Date: Fri, 29 Nov 2024 16:10:48 +0000 Subject: [PATCH] add policy e2e Signed-off-by: Zhiwei Yin --- go.mod | 17 ++-- go.sum | 47 +++++------ test/e2e/e2e_suite_test.go | 30 ++++++- test/e2e/helpers.go | 59 +++++++++++--- test/e2e/hosted_cluster_test.go | 137 ++++++++++++++++++++++++++++++++ test/e2e/local_cluster_test.go | 34 ++++---- test/e2e/policy_resouces.go | 97 ++++++++++++++++++++++ 7 files changed, 353 insertions(+), 68 deletions(-) create mode 100644 test/e2e/hosted_cluster_test.go create mode 100644 test/e2e/policy_resouces.go diff --git a/go.mod b/go.mod index 8ff45d9..f7c6098 100644 --- a/go.mod +++ b/go.mod @@ -14,21 +14,21 @@ require ( require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/google/uuid v1.6.0 // indirect - github.com/imdario/mergo v0.3.6 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -37,12 +37,13 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect + go.uber.org/zap v1.27.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/term v0.25.0 // indirect golang.org/x/text v0.19.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.26.0 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -50,7 +51,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.31.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/go.sum b/go.sum index d2172a4..7d0df2c 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,9 @@ -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= +github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= @@ -14,21 +13,20 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -39,19 +37,16 @@ github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgY github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -77,12 +72,7 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -91,8 +81,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -120,8 +110,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -144,7 +134,6 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= @@ -157,8 +146,8 @@ k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a h1:zD1uj3Jf+mD4zmA7W+goE5TxDkI7OGJjBNBzq5fJtLA= +k8s.io/kube-openapi v0.0.0-20240521193020-835d969ad83a/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= open-cluster-management.io/api v0.15.0 h1:lRee1KOlGHZb2scTA7ff9E9Fxt2hJc7jpkHnaCbvkOU= diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 3cf9ee9..5004f2d 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -1,6 +1,7 @@ package e2e import ( + "context" "fmt" "os" "testing" @@ -8,12 +9,16 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/tools/clientcmd" ) var ( - hubKubeConfig string - HubClients *Clients + hubKubeConfig string + HubClients *Clients + HostedClusterName string ) const ( @@ -22,8 +27,13 @@ const ( GovernancePolicyFrameworkAddonName = "governance-policy-framework" HypershiftAddonName = "hypershift-addon" WorkManagerAddonName = "work-manager" + mceName = "multiclusterengine" ) +var mceGVR = schema.GroupVersionResource{Group: "multicluster.openshift.io", Version: "v1", Resource: "multiclusterengines"} + +// - KUBECONFIG is the location of the kubeconfig file to use +// - MANAGED_CLUSTER_NAME is the name of managed cluster func TestE2E(tt *testing.T) { OutputFail := func(message string, callerSkip ...int) { ginkgo.Fail(message, callerSkip...) @@ -48,8 +58,22 @@ var _ = ginkgo.BeforeSuite(func() { gomega.Default.SetDefaultEventuallyTimeout(90 * time.Second) gomega.Default.SetDefaultEventuallyPollingInterval(5 * time.Second) - ginkgo.By("Check Hub Ready") + ginkgo.By("Check if MCE is Ready") gomega.Eventually(func() error { + mce, err := HubClients.DynamicClient.Resource(mceGVR).Get(context.TODO(), mceName, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get mce: %v", err) + } + mcePhase, found, err := unstructured.NestedString(mce.Object, "status", "phase") + if err != nil { + return fmt.Errorf("failed to get mce status: %v", err) + } + if !found { + return fmt.Errorf("failed found phase in the status of mce") + } + if mcePhase != "Available" { + return fmt.Errorf("the mce status is not Available") + } return nil }).Should(gomega.Succeed()) }) diff --git a/test/e2e/helpers.go b/test/e2e/helpers.go index e227296..e62454c 100644 --- a/test/e2e/helpers.go +++ b/test/e2e/helpers.go @@ -1,8 +1,15 @@ package e2e import ( + "context" "fmt" + "os" + + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "open-cluster-management.io/api/addon/v1alpha1" clusterv1 "open-cluster-management.io/api/cluster/v1" ) @@ -40,18 +47,50 @@ func CheckManagedClusterStatus(cluster *clusterv1.ManagedCluster) error { } func CheckAddonStatus(addon v1alpha1.ManagedClusterAddOn) error { - var okCount = 0 - for _, condition := range addon.Status.Conditions { - if (condition.Type == v1alpha1.ManagedClusterAddOnConditionAvailable || - condition.Type == v1alpha1.ManagedClusterAddOnManifestApplied) && - condition.Status == metav1.ConditionTrue { - okCount++ - } + if !meta.IsStatusConditionTrue(addon.Status.Conditions, v1alpha1.ManagedClusterAddOnConditionAvailable) { + return fmt.Errorf("addon %s is not Available: %v", addon.Name, addon.Status.Conditions) } - if okCount == 2 { - return nil + return nil +} + +func ApplyResource(gvr schema.GroupVersionResource, obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { + namespace := obj.GetNamespace() + name := obj.GetName() + + _, err := HubClients.DynamicClient.Resource(gvr).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil && errors.IsNotFound(err) { + return HubClients.DynamicClient.Resource(gvr).Namespace(namespace).Create(context.TODO(), obj, metav1.CreateOptions{}) + } + if err == nil { + return nil, nil } - return fmt.Errorf("cluster %s condtions are not ready: %v", addon.Name, addon.Status.Conditions) + return nil, err +} + +func DeleteResource(gvr schema.GroupVersionResource, namespace, name string) error { + return HubClients.DynamicClient.Resource(gvr).Namespace(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) +} + +func GetResource(gvr schema.GroupVersionResource, namespace, name string) (*unstructured.Unstructured, error) { + obj, err := HubClients.DynamicClient.Resource(gvr).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + return obj, nil +} + +func LoadResourceFromJSON(json string) (*unstructured.Unstructured, error) { + obj := unstructured.Unstructured{} + err := obj.UnmarshalJSON([]byte(json)) + return &obj, err +} + +func GetManagedClusterName() string { + if HostedClusterName == "" { + return os.Getenv("MANAGED_CLUSTER_NAME") + } + return HostedClusterName } diff --git a/test/e2e/hosted_cluster_test.go b/test/e2e/hosted_cluster_test.go new file mode 100644 index 0000000..33f6a1d --- /dev/null +++ b/test/e2e/hosted_cluster_test.go @@ -0,0 +1,137 @@ +package e2e + +import ( + "context" + "fmt" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +var _ = Describe("Check the status of hosted cluster.\n", Label("hosted cluster"), func() { + var HostedClusterName string + var policyName, policyNamespace, policyInClusterName string + var placementBindingName, placementBindingNamespace string + + BeforeEach(func() { + HostedClusterName = GetManagedClusterName() + if HostedClusterName == "" { + fmt.Printf("the hosted cluster name is empty. SKIP.\n") + return + } + + By(fmt.Sprintf("Check the status of the hosted cluster %s.", HostedClusterName)) + Eventually(func() error { + cluster, err := HubClients.ClusterClient.ClusterV1().ManagedClusters().Get(context.Background(), + HostedClusterName, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed get hosted cluster: %v", err) + } + return CheckManagedClusterStatus(cluster) + }).Should(Succeed()) + + By(fmt.Sprintf("Check the status of addons on the hosted cluster %s.", HostedClusterName)) + Eventually(func() error { + addons, err := HubClients.AddonClient.AddonV1alpha1().ManagedClusterAddOns(HostedClusterName). + List(context.Background(), metav1.ListOptions{}) + if err != nil { + return fmt.Errorf("failed list addons: %v", err) + } + + if len(addons.Items) != 3 { + return fmt.Errorf("expect 3 addons but got %v", len(addons.Items)) + } + + for _, addon := range addons.Items { + switch addon.Name { + case WorkManagerAddonName, GovernancePolicyFrameworkAddonName, ConfigPolicyAddonName: + if err := CheckAddonStatus(addon); err != nil { + return err + } + + default: + return fmt.Errorf("unexpected addon: %s", addon.Name) + } + } + return nil + }).Should(Succeed()) + + By("Apply placementBinding and policy.") + policy, err := LoadResourceFromJSON(PolicyTemplate) + Expect(err).ToNot(HaveOccurred()) + _, err = ApplyResource(PolicyGVR, policy) + Expect(err).ToNot(HaveOccurred()) + + placementBinding, err := LoadResourceFromJSON(PlacementBindingTemplate) + Expect(err).ToNot(HaveOccurred()) + _, err = ApplyResource(PlacementBindingGVR, placementBinding) + Expect(err).ToNot(HaveOccurred()) + + policyName = policy.GetName() + policyNamespace = policy.GetNamespace() + policyInClusterName = fmt.Sprintf("%s.%s", policyNamespace, policyName) + placementBindingName = placementBinding.GetName() + placementBindingNamespace = placementBinding.GetNamespace() + + }) + + AfterEach(func() { + if HostedClusterName == "" { + fmt.Printf("the hosted cluster name is empty. SKIP.\n") + return + } + + By("Delete policy") + err := DeleteResource(PolicyGVR, policyNamespace, policyName) + Expect(err).ToNot(HaveOccurred()) + err = DeleteResource(PlacementBindingGVR, placementBindingNamespace, placementBindingName) + Expect(err).ToNot(HaveOccurred()) + }) + + It("Create policy and check the policy.\n", func() { + if HostedClusterName == "" { + fmt.Printf("the hosted cluster name is empty. SKIP.\n") + return + } + + By("Check the policy in the cluster ns.") + Eventually(func() error { + policyInClusterNs, err := GetResource(PolicyGVR, HostedClusterName, policyInClusterName) + if err != nil { + return fmt.Errorf("failed to get policy in hosted cluster ns %v. %v", HostedClusterName, err) + } + compliant, found, err := unstructured.NestedString(policyInClusterNs.Object, "status", "compliant") + if err != nil { + return fmt.Errorf("failed to get policy in hosted cluster ns %v: %v", HostedClusterName, err) + } + if !found { + return fmt.Errorf("failed found compliant in the status of policy %v", policyInClusterName) + } + if compliant != "NonCompliant" { + return fmt.Errorf("the policy status is not NonCompliant") + } + return nil + }).Should(Succeed()) + + By("Check the policy in the klusterlet ns.") + Eventually(func() error { + klusterletNs := fmt.Sprintf("klusterlet-%s", HostedClusterName) + policyInKlusterletNs, err := GetResource(PolicyGVR, klusterletNs, policyInClusterName) + if err != nil { + return fmt.Errorf("failed to get policy in klusterlet ns %v. %v", klusterletNs, err) + } + compliant, found, err := unstructured.NestedString(policyInKlusterletNs.Object, "status", "compliant") + if err != nil { + return fmt.Errorf("failed to get policy in klusterlet ns %v. %v", klusterletNs, err) + } + if !found { + return fmt.Errorf("failed found compliant in the status of policy %v", policyInClusterName) + } + if compliant != "NonCompliant" { + return fmt.Errorf("the policy status is not NonCompliant") + } + return nil + }).Should(Succeed()) + }) +}) diff --git a/test/e2e/local_cluster_test.go b/test/e2e/local_cluster_test.go index 03d5173..2b1596d 100644 --- a/test/e2e/local_cluster_test.go +++ b/test/e2e/local_cluster_test.go @@ -3,33 +3,31 @@ package e2e import ( "context" "fmt" - "github.com/onsi/ginkgo/v2" - "github.com/onsi/gomega" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -var _ = ginkgo.Describe("check if local-cluster is healthy", func() { - - ginkgo.BeforeEach(func() { - - }) - ginkgo.AfterEach(func() { - - }) - - ginkgo.It("check status of the local-cluster", func() { - gomega.Eventually(func() error { +var _ = Describe("Check the status of local-cluster.\n", Label("local-cluster"), func() { + BeforeEach(func() { + By("Check the status of local-cluster.") + Eventually(func() error { cluster, err := HubClients.ClusterClient.ClusterV1().ManagedClusters().Get(context.Background(), LocalClusterName, metav1.GetOptions{}) if err != nil { return fmt.Errorf("failed get local-cluster: %v", err) } return CheckManagedClusterStatus(cluster) - }).Should(gomega.Succeed()) + }).Should(Succeed()) + }) + + AfterEach(func() { + }) - ginkgo.It("check status of the addons in local-cluster", func() { - gomega.Eventually(func() error { + It("Check status of the addons in local-cluster.\n", func() { + By("Check status of the addons in local-cluster.") + Eventually(func() error { addons, err := HubClients.AddonClient.AddonV1alpha1().ManagedClusterAddOns(LocalClusterName). List(context.Background(), metav1.ListOptions{}) if err != nil { @@ -44,7 +42,7 @@ var _ = ginkgo.Describe("check if local-cluster is healthy", func() { switch addon.Name { case WorkManagerAddonName, HypershiftAddonName, GovernancePolicyFrameworkAddonName, ConfigPolicyAddonName: if err := CheckAddonStatus(addon); err != nil { - return fmt.Errorf("addon %v status is not avaiable: %v", addon.Name, err) + return err } default: @@ -52,6 +50,6 @@ var _ = ginkgo.Describe("check if local-cluster is healthy", func() { } } return nil - }).Should(gomega.Succeed()) + }).Should(Succeed()) }) }) diff --git a/test/e2e/policy_resouces.go b/test/e2e/policy_resouces.go new file mode 100644 index 0000000..3fa1afa --- /dev/null +++ b/test/e2e/policy_resouces.go @@ -0,0 +1,97 @@ +package e2e + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const PolicyTemplate = `{ + "apiVersion": "policy.open-cluster-management.io/v1", + "kind": "Policy", + "metadata": { + "annotations": { + "policy.open-cluster-management.io/categories": "PR.PT Protective Technology", + "policy.open-cluster-management.io/controls": "PR.PT-3 Least Functionality", + "policy.open-cluster-management.io/standards": "NIST-CSF" + }, + "name": "test-pod-policy", + "namespace": "open-cluster-management-global-set" + }, + "spec": { + "disabled": false, + "policy-templates": [ + { + "objectDefinition": { + "apiVersion": "policy.open-cluster-management.io/v1", + "kind": "ConfigurationPolicy", + "metadata": { + "name": "test-pod-policy-nginx-pod" + }, + "spec": { + "namespaceSelector": { + "exclude": [ + "kube-*" + ], + "include": [ + "default" + ] + }, + "object-templates": [ + { + "complianceType": "musthave", + "objectDefinition": { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "nginx-pod-test" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.18.0", + "name": "nginx", + "ports": [ + { + "containerPort": 80 + } + ] + } + ] + } + } + } + ], + "remediationAction": "inform", + "severity": "low" + } + } + } + ], + "remediationAction": "inform" + } +}` + +const PlacementBindingTemplate = `{ + "apiVersion": "policy.open-cluster-management.io/v1", + "kind": "PlacementBinding", + "metadata": { + "name": "test-placementbinding", + "namespace": "open-cluster-management-global-set" + }, + "placementRef": { + "apiGroup": "cluster.open-cluster-management.io", + "kind": "Placement", + "name": "global" + }, + "subjects": [ + { + "apiGroup": "policy.open-cluster-management.io", + "kind": "Policy", + "name": "test-pod-policy" + } + ] +}` + +var ( + PolicyGVR = schema.GroupVersionResource{Group: "policy.open-cluster-management.io", Version: "v1", Resource: "policies"} + PlacementBindingGVR = schema.GroupVersionResource{Group: "policy.open-cluster-management.io", Version: "v1", Resource: "placementbindings"} +)