diff --git a/go.mod b/go.mod index b672244bdbe9..ea09b9a5d12c 100644 --- a/go.mod +++ b/go.mod @@ -34,11 +34,11 @@ require ( github.com/onsi/ginkgo v4.5.0-origin.1+incompatible github.com/onsi/gomega v1.7.0 github.com/opencontainers/go-digest v1.0.0-rc1 - github.com/openshift/api v0.0.0-20200722204502-c33fd0aa6ffa - github.com/openshift/apiserver-library-go v0.0.0-20200723181026-dd21ec96ba0a - github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7 - github.com/openshift/client-go v0.0.0-20200722173614-5a1b0aaeff15 - github.com/openshift/library-go v0.0.0-20200722204747-e3f2c82ff290 + github.com/openshift/api v0.0.0-20200829102639-8a3a835f1acf + github.com/openshift/apiserver-library-go v0.0.0-20200901140731-1236dc23c728 + github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7 + github.com/openshift/client-go v0.0.0-20200827190008-3062137373b5 + github.com/openshift/library-go v0.0.0-20200902112127-a4e32e339219 github.com/pborman/uuid v1.2.0 github.com/pquerna/cachecontrol v0.0.0-00010101000000-000000000000 // indirect github.com/prometheus/client_golang v1.7.1 @@ -52,24 +52,24 @@ require ( github.com/urfave/negroni v0.0.0-00010101000000-000000000000 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.etcd.io/etcd v3.3.17+incompatible - golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 - golang.org/x/net v0.0.0-20200602114024-627f9648deb9 + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 + golang.org/x/net v0.0.0-20200707034311-ab3426394381 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 google.golang.org/grpc v1.27.1 gopkg.in/src-d/go-git.v4 v4.13.1 gopkg.in/yaml.v2 v2.3.0 - k8s.io/api v0.19.0-rc.2 - k8s.io/apiextensions-apiserver v0.19.0-rc.2 - k8s.io/apimachinery v0.19.0-rc.2 - k8s.io/apiserver v0.19.0-rc.2 + k8s.io/api v0.19.0 + k8s.io/apiextensions-apiserver v0.19.0 + k8s.io/apimachinery v0.19.0 + k8s.io/apiserver v0.19.0 k8s.io/cli-runtime v0.19.0-rc.2 - k8s.io/client-go v0.19.0-rc.2 - k8s.io/component-base v0.19.0-rc.2 + k8s.io/client-go v0.19.0 + k8s.io/component-base v0.19.0 k8s.io/klog v1.0.0 - k8s.io/kube-openapi v0.0.0-20200427153329-656914f816f9 + k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 k8s.io/kubectl v0.0.0 k8s.io/kubelet v0.0.0 - k8s.io/kubernetes v1.19.0-rc.2 + k8s.io/kubernetes v1.19.0 k8s.io/legacy-cloud-providers v0.0.0 sigs.k8s.io/yaml v1.2.0 ) @@ -420,10 +420,10 @@ replace ( k8s.io/api => k8s.io/api v0.19.0-rc.2 k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.19.0-rc.2 k8s.io/apimachinery => k8s.io/apimachinery v0.19.0-rc.2 - k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20200826132615-f71a7ab366cf + k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20200916071455-b4ffb455315c k8s.io/cli-runtime => k8s.io/cli-runtime v0.19.0-rc.2 - k8s.io/client-go => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20200826132615-f71a7ab366cf - k8s.io/cloud-provider => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20200826132615-f71a7ab366cf + k8s.io/client-go => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20200916071455-b4ffb455315c + k8s.io/cloud-provider => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20200916071455-b4ffb455315c k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.19.0-rc.2 k8s.io/code-generator => k8s.io/code-generator v0.19.0-rc.2 k8s.io/component-base => k8s.io/component-base v0.19.0-rc.2 @@ -432,14 +432,14 @@ replace ( k8s.io/gengo => k8s.io/gengo v0.0.0-20200114144118-36b2048a9120 k8s.io/heapster => k8s.io/heapster v1.2.0-beta.1 k8s.io/klog => k8s.io/klog v1.0.0 - k8s.io/kube-aggregator => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20200826132615-f71a7ab366cf + k8s.io/kube-aggregator => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20200916071455-b4ffb455315c k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.19.0-rc.2 k8s.io/kube-proxy => k8s.io/kube-proxy v0.19.0-rc.2 k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.19.0-rc.2 k8s.io/kubectl => k8s.io/kubectl v0.19.0-rc.2 k8s.io/kubelet => k8s.io/kubelet v0.19.0-rc.2 - k8s.io/kubernetes => github.com/openshift/kubernetes v1.20.0-alpha.0.0.20200826132615-f71a7ab366cf - k8s.io/legacy-cloud-providers => github.com/openshift/kubernetes/staging/src/k8s.io/legacy-cloud-providers v0.0.0-20200826132615-f71a7ab366cf + k8s.io/kubernetes => github.com/openshift/kubernetes v1.20.0-alpha.0.0.20200916071455-b4ffb455315c + k8s.io/legacy-cloud-providers => github.com/openshift/kubernetes/staging/src/k8s.io/legacy-cloud-providers v0.0.0-20200916071455-b4ffb455315c k8s.io/metrics => k8s.io/metrics v0.19.0-rc.2 k8s.io/repo-infra => k8s.io/repo-infra v0.0.1-alpha.1 k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.19.0-rc.2 diff --git a/go.sum b/go.sum index ea03aa44f82a..b7885386ce5d 100644 --- a/go.sum +++ b/go.sum @@ -425,31 +425,32 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.m github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.5.2 h1:F6DgIsjgBIcDksLW4D5RG9bXok6oqZ3nvMwj4ZoFu/Q= github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= -github.com/openshift/api v0.0.0-20200722170803-0ba2c3658da6/go.mod h1:IXsT3F4NjLtRzfnQvwU+g/oPWpoNsVV5vd5aaOMO8eU= -github.com/openshift/api v0.0.0-20200722204502-c33fd0aa6ffa h1:Ty11UANoi60q8bnaA/XHornmFFzRDkYHwWE2fQMNzqQ= -github.com/openshift/api v0.0.0-20200722204502-c33fd0aa6ffa/go.mod h1:IXsT3F4NjLtRzfnQvwU+g/oPWpoNsVV5vd5aaOMO8eU= -github.com/openshift/apiserver-library-go v0.0.0-20200723181026-dd21ec96ba0a h1:5jNauFKxYwStYVdLRY+Oy+hS/8h1wioW5RYaIWXFpC8= -github.com/openshift/apiserver-library-go v0.0.0-20200723181026-dd21ec96ba0a/go.mod h1://gQP1LMTExUTcFCgJdKHY23UVHhkaQILXsTdVz0Qok= -github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7 h1:iP7TOaN+tEVNUQ0ODEbN1ukjLz918lsIt7Czf8giWlM= -github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= -github.com/openshift/client-go v0.0.0-20200722173614-5a1b0aaeff15 h1:b2QkHrmaYtY6kzy2VrYLc+KBmCuTpJjgvBahPqpt6V0= -github.com/openshift/client-go v0.0.0-20200722173614-5a1b0aaeff15/go.mod h1:yd4Zpcdk+8JyMWi6v+h78jPqK0FvXbJY41Wq3SZxl+c= +github.com/openshift/api v0.0.0-20200827090112-c05698d102cf/go.mod h1:M3xexPhgM8DISzzRpuFUy+jfPjQPIcs9yqEYj17mXV8= +github.com/openshift/api v0.0.0-20200829102639-8a3a835f1acf h1:KP/v5AGCaq1Sbe6QrlFGZM1fHBswiHuniMTC4/hgbVw= +github.com/openshift/api v0.0.0-20200829102639-8a3a835f1acf/go.mod h1:M3xexPhgM8DISzzRpuFUy+jfPjQPIcs9yqEYj17mXV8= +github.com/openshift/apiserver-library-go v0.0.0-20200901140731-1236dc23c728 h1:QOA50MXyDwiKs+Pskg7D18yZ1Z5kbxNDqQkmT7CAbdw= +github.com/openshift/apiserver-library-go v0.0.0-20200901140731-1236dc23c728/go.mod h1:+B51GHs/jfZzk93MKrSSA8BWxrulVVcxiBG7kdFpd74= +github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7 h1:mOq7Mg1Q9d7nIDxe1SJ6pluMBQsbVxa6olyAGmfYWTg= +github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= +github.com/openshift/client-go v0.0.0-20200827190008-3062137373b5 h1:E6WhVL5p3rfjtc+o+jVG/29Aclnf3XIF7akxXvadwR0= +github.com/openshift/client-go v0.0.0-20200827190008-3062137373b5/go.mod h1:5rGmrkQ8DJEUXA+AR3rEjfH+HFyg4/apY9iCQFgvPfE= github.com/openshift/golang-glog v0.0.0-20190322123450-3c92600d7533 h1:A5VovyRu3JFIPmC20HHrsOOny0PIdHuzDdNMULru48k= github.com/openshift/golang-glog v0.0.0-20190322123450-3c92600d7533/go.mod h1:3sa6LKKRDnR1xy4Kn8htvPwqIOVwXh8fIU3LRY22q3U= -github.com/openshift/kubernetes v1.20.0-alpha.0.0.20200826132615-f71a7ab366cf h1:ZN/QjGb0pIrsNQYpBTEveZzFoPqv7P26JB/nsKzZ6n4= -github.com/openshift/kubernetes v1.20.0-alpha.0.0.20200826132615-f71a7ab366cf/go.mod h1:aJkJxeDTYuttw+MRc5T2zhDsP24ZhZmpGmc+jmdz7w0= -github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20200826132615-f71a7ab366cf h1:N8rG0zKTjJRuTO0UfQDXaxaBEtLTULxncmcgBScaWgI= -github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20200826132615-f71a7ab366cf/go.mod h1:q9rHEv1UltcR8OSRYNAJOOiS8HrCX9U7I2RacSAr4XM= -github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20200826132615-f71a7ab366cf h1:5JYxm4t7jUPEoLiFViiqcPujntSOztnOSuGybRItBOU= -github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20200826132615-f71a7ab366cf/go.mod h1:+D+tDV3iwgbrqITjgufYYBkYVIfzD564qL10LbnKzgM= -github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20200826132615-f71a7ab366cf h1:dKA2Rmv4nZJphas3gtH8W98+ZRMrFrZjKkMj+Ucj/gk= -github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20200826132615-f71a7ab366cf/go.mod h1:vx/reZx/iefWuS3A7hRi4cwoptpCkVhqqITKpUsIkWs= -github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20200826132615-f71a7ab366cf h1:A30pBAUeL4ogH6sAamr346lPGvNybGo/2YO/POhHPc4= -github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20200826132615-f71a7ab366cf/go.mod h1:MUq2YTU8mwp7qYhM8Gu95ZSBOIp2+OyDSY7dOeHgCTA= -github.com/openshift/kubernetes/staging/src/k8s.io/legacy-cloud-providers v0.0.0-20200826132615-f71a7ab366cf h1:6WYK5JAFYXehPZbVkkkSqeibs7clN3mRHZmiXG+K79w= -github.com/openshift/kubernetes/staging/src/k8s.io/legacy-cloud-providers v0.0.0-20200826132615-f71a7ab366cf/go.mod h1:kUaainILK6Zy9oE3FRx+pp7y5+eTb73H3Z4oEmzaxQ8= -github.com/openshift/library-go v0.0.0-20200722204747-e3f2c82ff290 h1:x2MMkmR0gr+3UazejQcIafWCXh8d0W+6EWTtWLyGBnQ= -github.com/openshift/library-go v0.0.0-20200722204747-e3f2c82ff290/go.mod h1:/gVyoY2dl35bcCCgs+36UmGt6n/kn3f64hfDduujQ1c= +github.com/openshift/kubernetes v1.20.0-alpha.0.0.20200916071455-b4ffb455315c h1:jD6cVZyM556uGX9OivnDFTPJe7bzAR9stk2KILhagUM= +github.com/openshift/kubernetes v1.20.0-alpha.0.0.20200916071455-b4ffb455315c/go.mod h1:thZ+fVBomGpLqnFpgVP7zLoR1cZr5ceY0Ccrrw5DUPc= +github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20200916071455-b4ffb455315c h1:gGdcYg6AtITQcdWMEDKp0qEVN+F8xtCcYz8ieMkyTqg= +github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20200916071455-b4ffb455315c/go.mod h1:wR/2WpnpEiQEhbGJyD7pRwxVsSEW4H3QKgvH4LBr97I= +github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20200916071455-b4ffb455315c h1:BWLL/lZS2MGdsa5t3jFlGBfFaRUp82vu8TE79jmA+us= +github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20200916071455-b4ffb455315c/go.mod h1:PKE732z15ZBntzuIso4UituryF6ls1srirW354KG/ag= +github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20200916071455-b4ffb455315c h1:YwJOlL5HENeKlGLqFoRH7X0tyvz1y612NhXdn21q1WE= +github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20200916071455-b4ffb455315c/go.mod h1:xzTMREjOlgHSSvy4fYZPWLzPkYSn7Y0QmDpP2v3KQ24= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20200916071455-b4ffb455315c h1:/fTHIq/Drd5/7w/Ow1DC+mbaq2TPb2rLVT2YMK0XR1c= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20200916071455-b4ffb455315c/go.mod h1:DaF/5oFo8hXpqC477u574XitO+uLNInMmaSkNYJiDSU= +github.com/openshift/kubernetes/staging/src/k8s.io/legacy-cloud-providers v0.0.0-20200916071455-b4ffb455315c h1:PdThuYr/HYr+Wds4mpoZgHfKho56+3vAp/9BJyn/EKc= +github.com/openshift/kubernetes/staging/src/k8s.io/legacy-cloud-providers v0.0.0-20200916071455-b4ffb455315c/go.mod h1:Jsv6Huoke+fYBJz8CGV1m3A1EL3tOzSvQKiC0O6ohTQ= +github.com/openshift/library-go v0.0.0-20200831114015-2ab0c61c15de/go.mod h1:6vwp+YhYOIlj8MpkQKkebTTSn2TuYyvgiAFQ206jIEQ= +github.com/openshift/library-go v0.0.0-20200902112127-a4e32e339219 h1:dhz1PgLYnWYpfXad452f/5P0wMU6MZvOlPIkPRzK7ro= +github.com/openshift/library-go v0.0.0-20200902112127-a4e32e339219/go.mod h1:6vwp+YhYOIlj8MpkQKkebTTSn2TuYyvgiAFQ206jIEQ= github.com/openshift/onsi-ginkgo v4.5.0-origin.1+incompatible h1:GtzyDU5vBFU40hz4GWd1qU5FJByNljWdgkM2LtdelGk= github.com/openshift/onsi-ginkgo v4.5.0-origin.1+incompatible/go.mod h1:azqkkH4Vpp9A579CC26hicol/wViXag9rOwElif6v9E= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= @@ -685,9 +686,13 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.3.0 h1:WmkrnW7fdrm0/DMClc+HIxtftvxVIPAhlVwMQo5yLco= +k8s.io/klog/v2 v2.3.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/kube-controller-manager v0.19.0-rc.2/go.mod h1:WlVUi/rJKZUMBwOFUts9fMFVaPZCxxtoP2pVyyD+UnM= k8s.io/kube-openapi v0.0.0-20200427153329-656914f816f9 h1:5NC2ITmvg8RoxoH0wgmL4zn4VZqXGsKbxrikjaQx6s4= k8s.io/kube-openapi v0.0.0-20200427153329-656914f816f9/go.mod h1:bfCVj+qXcEaE5SCvzBaqpOySr6tuCcpPKqF6HD8nyCw= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-proxy v0.19.0-rc.2 h1:LUbz06HRHVbwDdfF1U1GfiUUvI8kcnI1rDCwPd8DWYo= k8s.io/kube-proxy v0.19.0-rc.2/go.mod h1:wseT7Qp6fXNDEKXX0g7vWU/RpaWOACM4yrjzB8gixJA= k8s.io/kube-scheduler v0.19.0-rc.2 h1:G7ngD0v3MwjnMMqSwO952y1CmaMepGQZ+L2dCJxAdZY= @@ -715,6 +720,8 @@ sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbL sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/vendor/github.com/openshift/api/Makefile b/vendor/github.com/openshift/api/Makefile index 4043bf04fd11..7993192b6ae8 100644 --- a/vendor/github.com/openshift/api/Makefile +++ b/vendor/github.com/openshift/api/Makefile @@ -13,6 +13,7 @@ GO_BUILD_PACKAGES :=$(GO_PACKAGES) GO_BUILD_PACKAGES_EXPANDED :=$(GO_BUILD_PACKAGES) # LDFLAGS are not needed for dummy builds (saving time on calling git commands) GO_LD_FLAGS:= +CONTROLLER_GEN_VERSION :=v0.2.5 # $1 - target name # $2 - apis @@ -20,6 +21,7 @@ GO_LD_FLAGS:= # $4 - output $(call add-crd-gen,authorization,./authorization/v1,./authorization/v1,./authorization/v1) $(call add-crd-gen,config,./config/v1,./config/v1,./config/v1) +$(call add-crd-gen,helm,./helm/v1beta1,./helm/v1beta1,./helm/v1beta1) $(call add-crd-gen,console,./console/v1,./console/v1,./console/v1) $(call add-crd-gen,imageregistry,./imageregistry/v1,./imageregistry/v1,./imageregistry/v1) $(call add-crd-gen,operator,./operator/v1,./operator/v1,./operator/v1) @@ -52,4 +54,4 @@ update: update-scripts update-codegen-crds generate-with-container: Dockerfile.build $(RUNTIME) build -t $(RUNTIME_IMAGE_NAME) -f Dockerfile.build . - $(RUNTIME) run -ti --rm -v $(PWD):/go/src/github.com/openshift/api:z -w /go/src/github.com/openshift/api $(RUNTIME_IMAGE_NAME) make update-scripts + $(RUNTIME) run -ti --rm -v $(PWD):/go/src/github.com/openshift/api:z -w /go/src/github.com/openshift/api $(RUNTIME_IMAGE_NAME) make update diff --git a/vendor/github.com/openshift/api/README.md b/vendor/github.com/openshift/api/README.md index 60a7e0d7db5d..d20dfd71f4d3 100644 --- a/vendor/github.com/openshift/api/README.md +++ b/vendor/github.com/openshift/api/README.md @@ -66,4 +66,15 @@ After this, calling `make update-codegen-crds` should generate a new structural 1. `// +groupName=`, this should match the `group` in your CRD `spec` 2. `// +kubebuilder:validation:Optional`, this tells the operator that fields should be optional unless explicitly marked with `// +kubebuilder:validation:Required` -For more information on the API markers to add to your Go types, see the [Kubebuilder book](https://book.kubebuilder.io/reference/markers.html) \ No newline at end of file +For more information on the API markers to add to your Go types, see the [Kubebuilder book](https://book.kubebuilder.io/reference/markers.html) + +### Post-schema-generation Patches + +Schema generation features might be limited or fall behind what CRD schemas supports in the latest Kubernetes version. +To work around this, there are two patch mechanisms implemented by the `add-crd-gen` target. Basic idea is that you +place a patch file next to the CRD yaml manifest with either `yaml-merge-patch` or `yaml-patch` as extension, +but with the same base name. The `update-codegen-crds` Makefile target will apply these **after** calling +kubebuilder's controller-gen: + +- `yaml-merge-patch`: these are applied via `yq m -x ` compare https://mikefarah.gitbook.io/yq/commands/merge#overwrite-values. +- `yaml-patch`: these are applied via `yaml-patch -o < ` using https://github.com/krishicks/yaml-patch. diff --git a/vendor/github.com/openshift/api/authorization/v1/0000_03_authorization-openshift_01_rolebindingrestriction.crd.yaml b/vendor/github.com/openshift/api/authorization/v1/0000_03_authorization-openshift_01_rolebindingrestriction.crd.yaml index cbbe69d2841e..5fbc03c98b14 100644 --- a/vendor/github.com/openshift/api/authorization/v1/0000_03_authorization-openshift_01_rolebindingrestriction.crd.yaml +++ b/vendor/github.com/openshift/api/authorization/v1/0000_03_authorization-openshift_01_rolebindingrestriction.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: rolebindingrestrictions.authorization.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: authorization.openshift.io names: diff --git a/vendor/github.com/openshift/api/build/v1/generated.proto b/vendor/github.com/openshift/api/build/v1/generated.proto index 46470b12c1fd..52910663fd94 100644 --- a/vendor/github.com/openshift/api/build/v1/generated.proto +++ b/vendor/github.com/openshift/api/build/v1/generated.proto @@ -687,6 +687,7 @@ message DockerBuildStrategy { // dockerfilePath is the path of the Dockerfile that will be used to build the container image, // relative to the root of the context (contextDir). + // Defaults to `Dockerfile` if unset. optional string dockerfilePath = 6; // buildArgs contains build arguments that will be resolved in the Dockerfile. See diff --git a/vendor/github.com/openshift/api/build/v1/types.go b/vendor/github.com/openshift/api/build/v1/types.go index 1b233b535916..3c9d088f7ee2 100644 --- a/vendor/github.com/openshift/api/build/v1/types.go +++ b/vendor/github.com/openshift/api/build/v1/types.go @@ -713,6 +713,7 @@ type DockerBuildStrategy struct { // dockerfilePath is the path of the Dockerfile that will be used to build the container image, // relative to the root of the context (contextDir). + // Defaults to `Dockerfile` if unset. DockerfilePath string `json:"dockerfilePath,omitempty" protobuf:"bytes,6,opt,name=dockerfilePath"` // buildArgs contains build arguments that will be resolved in the Dockerfile. See diff --git a/vendor/github.com/openshift/api/build/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/build/v1/zz_generated.swagger_doc_generated.go index be0323039f04..f54e07222b5c 100644 --- a/vendor/github.com/openshift/api/build/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/build/v1/zz_generated.swagger_doc_generated.go @@ -347,7 +347,7 @@ var map_DockerBuildStrategy = map[string]string{ "noCache": "noCache if set to true indicates that the container image build must be executed with the --no-cache=true flag", "env": "env contains additional environment variables you want to pass into a builder container.", "forcePull": "forcePull describes if the builder should pull the images from registry prior to building.", - "dockerfilePath": "dockerfilePath is the path of the Dockerfile that will be used to build the container image, relative to the root of the context (contextDir).", + "dockerfilePath": "dockerfilePath is the path of the Dockerfile that will be used to build the container image, relative to the root of the context (contextDir). Defaults to `Dockerfile` if unset.", "buildArgs": "buildArgs contains build arguments that will be resolved in the Dockerfile. See https://docs.docker.com/engine/reference/builder/#/arg for more details.", "imageOptimizationPolicy": "imageOptimizationPolicy describes what optimizations the system can use when building images to reduce the final size or time spent building the image. The default policy is 'None' which means the final build image will be equivalent to an image created by the container image build API. The experimental policy 'SkipLayers' will avoid commiting new layers in between each image step, and will fail if the Dockerfile cannot provide compatibility with the 'None' policy. An additional experimental policy 'SkipLayersAndWarn' is the same as 'SkipLayers' but simply warns if compatibility cannot be preserved.", } diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusteroperator.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusteroperator.crd.yaml index 114db5aec881..f7767a124248 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusteroperator.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusteroperator.crd.yaml @@ -2,6 +2,8 @@ kind: CustomResourceDefinition apiVersion: apiextensions.k8s.io/v1beta1 metadata: name: clusteroperators.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: additionalPrinterColumns: - JSONPath: .status.versions[?(@.name=="operator")].version diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml index ccde0db23bb7..b5dc54376d9b 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: clusterversions.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io versions: @@ -162,28 +164,29 @@ spec: channel has been specified. type: array items: - description: Update represents a release of the ClusterVersionOperator, - referenced by the Image member. + description: Release represents an OpenShift release image and associated + metadata. type: object properties: - force: - description: "force allows an administrator to update to an image - that has failed verification, does not appear in the availableUpdates - list, or otherwise would be blocked by normal protections on - update. This option should only be used when the authenticity - of the provided image has been verified out of band because - the provided image will run with full administrative access - to the cluster. Do not use this flag with images that comes - from unknown or potentially malicious sources. \n This flag - does not override other forms of consistency checking that are - required before a new update is deployed." - type: boolean + channels: + description: channels is the set of Cincinnati channels to which + the release currently belongs. + type: array + items: + type: string image: description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. type: string + url: + description: url contains information about this release. This + URL is set by the 'url' metadata property on a release or the + metadata returned by the update API and should be displayed + as a link in user interfaces. The URL field may not be set for + test or nightly releases. + type: string version: description: version is a semantic versioning identifying the update version. When this field is part of spec, version is @@ -234,24 +237,25 @@ spec: tag. type: object properties: - force: - description: "force allows an administrator to update to an image - that has failed verification, does not appear in the availableUpdates - list, or otherwise would be blocked by normal protections on update. - This option should only be used when the authenticity of the provided - image has been verified out of band because the provided image - will run with full administrative access to the cluster. Do not - use this flag with images that comes from unknown or potentially - malicious sources. \n This flag does not override other forms - of consistency checking that are required before a new update - is deployed." - type: boolean + channels: + description: channels is the set of Cincinnati channels to which + the release currently belongs. + type: array + items: + type: string image: description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. type: string + url: + description: url contains information about this release. This URL + is set by the 'url' metadata property on a release or the metadata + returned by the update API and should be displayed as a link in + user interfaces. The URL field may not be set for test or nightly + releases. + type: string version: description: version is a semantic versioning identifying the update version. When this field is part of spec, version is optional diff --git a/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_operatorhub.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_operatorhub.crd.yaml index 8c857d45a4b6..19994f42c52f 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_operatorhub.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_operatorhub.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: operatorhubs.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io names: diff --git a/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_proxy.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_proxy.crd.yaml index cf04b249b983..b6fb1c48ce7e 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_proxy.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_proxy.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: proxies.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io scope: Cluster diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver.crd.yaml index 398292f0dfd1..468ad078dae2 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver.crd.yaml @@ -1,11 +1,12 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: apiservers.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io scope: Cluster - preserveUnknownFields: false names: kind: APIServer singular: apiserver @@ -15,218 +16,243 @@ spec: - name: v1 served: true storage: true - subresources: - status: {} - "validation": - "openAPIV3Schema": - description: APIServer holds configuration (like serving certificates, client - CA and CORS domains) shared by all API servers in the system, among them especially - kube-apiserver and openshift-apiserver. The canonical name of an instance - is 'cluster'. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec holds user settable values for configuration - type: object - properties: - additionalCORSAllowedOrigins: - description: additionalCORSAllowedOrigins lists additional, user-defined - regular expressions describing hosts for which the API server allows - access using the CORS headers. This may be needed to access the API - and the integrated OAuth server from JavaScript applications. The - values are regular expressions that correspond to the Golang regular - expression language. - type: array - items: - type: string - clientCA: - description: 'clientCA references a ConfigMap containing a certificate - bundle for the signers that will be recognized for incoming client - certificates in addition to the operator managed signers. If this - is empty, then only operator managed signers are valid. You usually - only have to set this if you have your own PKI you wish to honor client - certificates from. The ConfigMap must exist in the openshift-config - namespace and contain the following required fields: - ConfigMap.Data["ca-bundle.crt"] - - CA bundle.' - type: object - required: - - name - properties: - name: - description: name is the metadata.name of the referenced config - map + subresources: + status: {} + schema: + "openAPIV3Schema": + description: APIServer holds configuration (like serving certificates, client + CA and CORS domains) shared by all API servers in the system, among them + especially kube-apiserver and openshift-apiserver. The canonical name of + an instance is 'cluster'. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + type: object + properties: + additionalCORSAllowedOrigins: + description: additionalCORSAllowedOrigins lists additional, user-defined + regular expressions describing hosts for which the API server allows + access using the CORS headers. This may be needed to access the + API and the integrated OAuth server from JavaScript applications. + The values are regular expressions that correspond to the Golang + regular expression language. + type: array + items: type: string - encryption: - description: encryption allows the configuration of encryption of resources - at the datastore layer. - type: object - properties: - type: - description: "type defines what encryption type should be used to - encrypt resources at the datastore layer. When this field is unset - (i.e. when it is set to the empty string), identity is implied. - The behavior of unset can and will change over time. Even if - encryption is enabled by default, the meaning of unset may change - to a different encryption type based on changes in best practices. - \n When encryption is enabled, all sensitive resources shipped - with the platform are encrypted. This list of sensitive resources - can and will change over time. The current authoritative list - is: \n 1. secrets 2. configmaps 3. routes.route.openshift.io - \ 4. oauthaccesstokens.oauth.openshift.io 5. oauthauthorizetokens.oauth.openshift.io" - type: string - enum: - - "" - - identity - - aescbc - servingCerts: - description: servingCert is the TLS cert info for serving secure traffic. - If not specified, operator managed certificates will be used for serving - secure traffic. - type: object - properties: - namedCertificates: - description: namedCertificates references secrets containing the - TLS cert info for serving secure traffic to specific hostnames. - If no named certificates are provided, or no named certificates - match the server name as understood by a client, the defaultServingCertificate - will be used. - type: array - items: - description: APIServerNamedServingCert maps a server DNS name, - as understood by a client, to a certificate. + audit: + description: audit specifies the settings for audit configuration + to be applied to all OpenShift-provided API servers in the cluster. + type: object + default: + profile: Default + properties: + profile: + description: "profile specifies the name of the desired audit + policy configuration to be deployed to all OpenShift-provided + API servers in the cluster. \n The following profiles are provided: + - Default: the existing default policy. - WriteRequestBodies: + like 'Default', but logs request and response HTTP payloads + for write requests (create, update, patch). - AllRequestBodies: + like 'WriteRequestBodies', but also logs request and response + HTTP payloads for read requests (get, list). \n If unset, the + 'Default' profile is used as the default." + type: string + default: Default + enum: + - Default + - WriteRequestBodies + - AllRequestBodies + clientCA: + description: 'clientCA references a ConfigMap containing a certificate + bundle for the signers that will be recognized for incoming client + certificates in addition to the operator managed signers. If this + is empty, then only operator managed signers are valid. You usually + only have to set this if you have your own PKI you wish to honor + client certificates from. The ConfigMap must exist in the openshift-config + namespace and contain the following required fields: - ConfigMap.Data["ca-bundle.crt"] + - CA bundle.' + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced config + map + type: string + encryption: + description: encryption allows the configuration of encryption of + resources at the datastore layer. + type: object + properties: + type: + description: "type defines what encryption type should be used + to encrypt resources at the datastore layer. When this field + is unset (i.e. when it is set to the empty string), identity + is implied. The behavior of unset can and will change over time. + \ Even if encryption is enabled by default, the meaning of unset + may change to a different encryption type based on changes in + best practices. \n When encryption is enabled, all sensitive + resources shipped with the platform are encrypted. This list + of sensitive resources can and will change over time. The current + authoritative list is: \n 1. secrets 2. configmaps 3. + routes.route.openshift.io 4. oauthaccesstokens.oauth.openshift.io + \ 5. oauthauthorizetokens.oauth.openshift.io" + type: string + enum: + - "" + - identity + - aescbc + servingCerts: + description: servingCert is the TLS cert info for serving secure traffic. + If not specified, operator managed certificates will be used for + serving secure traffic. + type: object + properties: + namedCertificates: + description: namedCertificates references secrets containing the + TLS cert info for serving secure traffic to specific hostnames. + If no named certificates are provided, or no named certificates + match the server name as understood by a client, the defaultServingCertificate + will be used. + type: array + items: + description: APIServerNamedServingCert maps a server DNS name, + as understood by a client, to a certificate. + type: object + properties: + names: + description: names is a optional list of explicit DNS names + (leading wildcards allowed) that should use this certificate + to serve secure traffic. If no names are provided, the + implicit names will be extracted from the certificates. + Exact names trump over wildcard names. Explicit names + defined here trump over extracted implicit names. + type: array + items: + type: string + servingCertificate: + description: 'servingCertificate references a kubernetes.io/tls + type secret containing the TLS cert info for serving secure + traffic. The secret must exist in the openshift-config + namespace and contain the following required fields: - + Secret.Data["tls.key"] - TLS private key. - Secret.Data["tls.crt"] + - TLS certificate.' + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + tlsSecurityProfile: + description: "tlsSecurityProfile specifies settings for TLS connections + for externally exposed servers. \n If unset, a default (which may + change between releases) is chosen. Note that only Old and Intermediate + profiles are currently supported, and the maximum available MinTLSVersions + is VersionTLS12." + type: object + properties: + custom: + description: "custom is a user-defined TLS security profile. Be + extremely careful using a custom profile as invalid configurations + can be catastrophic. An example custom profile looks like this: + \n ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 + \ - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 + \ minTLSVersion: TLSv1.1" type: object properties: - names: - description: names is a optional list of explicit DNS names - (leading wildcards allowed) that should use this certificate - to serve secure traffic. If no names are provided, the implicit - names will be extracted from the certificates. Exact names - trump over wildcard names. Explicit names defined here trump - over extracted implicit names. + ciphers: + description: "ciphers is used to specify the cipher algorithms + that are negotiated during the TLS handshake. Operators + may remove entries their operands do not support. For example, + to use DES-CBC3-SHA (yaml): \n ciphers: - DES-CBC3-SHA" type: array items: type: string - servingCertificate: - description: 'servingCertificate references a kubernetes.io/tls - type secret containing the TLS cert info for serving secure - traffic. The secret must exist in the openshift-config namespace - and contain the following required fields: - Secret.Data["tls.key"] - - TLS private key. - Secret.Data["tls.crt"] - TLS certificate.' - type: object - required: - - name - properties: - name: - description: name is the metadata.name of the referenced - secret - type: string - tlsSecurityProfile: - description: "tlsSecurityProfile specifies settings for TLS connections - for externally exposed servers. \n If unset, a default (which may - change between releases) is chosen. Note that only Old and Intermediate - profiles are currently supported, and the maximum available MinTLSVersions - is VersionTLS12." - type: object - properties: - custom: - description: "custom is a user-defined TLS security profile. Be - extremely careful using a custom profile as invalid configurations - can be catastrophic. An example custom profile looks like this: - \n ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - \ - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 - \ minTLSVersion: TLSv1.1" - type: object - properties: - ciphers: - description: "ciphers is used to specify the cipher algorithms - that are negotiated during the TLS handshake. Operators may - remove entries their operands do not support. For example, - to use DES-CBC3-SHA (yaml): \n ciphers: - DES-CBC3-SHA" - type: array - items: + minTLSVersion: + description: "minTLSVersion is used to specify the minimal + version of the TLS protocol that is negotiated during the + TLS handshake. For example, to use TLS versions 1.1, 1.2 + and 1.3 (yaml): \n minTLSVersion: TLSv1.1 \n NOTE: currently + the highest minTLSVersion allowed is VersionTLS12" type: string - minTLSVersion: - description: "minTLSVersion is used to specify the minimal version - of the TLS protocol that is negotiated during the TLS handshake. - For example, to use TLS versions 1.1, 1.2 and 1.3 (yaml): - \n minTLSVersion: TLSv1.1 \n NOTE: currently the highest - minTLSVersion allowed is VersionTLS12" - type: string - enum: - - VersionTLS10 - - VersionTLS11 - - VersionTLS12 - - VersionTLS13 - nullable: true - intermediate: - description: "intermediate is a TLS security profile based on: \n - https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29 - \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - \ - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - \ - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - \ - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - \ - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 - \ minTLSVersion: TLSv1.2" - type: object - nullable: true - modern: - description: "modern is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility - \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - \ minTLSVersion: TLSv1.3 \n NOTE: Currently unsupported." - type: object - nullable: true - old: - description: "old is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility - \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - \ - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - \ - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - \ - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - \ - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 - \ - DHE-RSA-CHACHA20-POLY1305 - ECDHE-ECDSA-AES128-SHA256 - \ - ECDHE-RSA-AES128-SHA256 - ECDHE-ECDSA-AES128-SHA - - ECDHE-RSA-AES128-SHA - ECDHE-ECDSA-AES256-SHA384 - ECDHE-RSA-AES256-SHA384 - \ - ECDHE-ECDSA-AES256-SHA - ECDHE-RSA-AES256-SHA - - DHE-RSA-AES128-SHA256 - DHE-RSA-AES256-SHA256 - AES128-GCM-SHA256 - \ - AES256-GCM-SHA384 - AES128-SHA256 - AES256-SHA256 - \ - AES128-SHA - AES256-SHA - DES-CBC3-SHA minTLSVersion: - TLSv1.0" - type: object - nullable: true - type: - description: "type is one of Old, Intermediate, Modern or Custom. - Custom provides the ability to specify individual TLS security - profile parameters. Old, Intermediate and Modern are TLS security - profiles based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations - \n The profiles are intent based, so they may change over time - as new ciphers are developed and existing ciphers are found to - be insecure. Depending on precisely which ciphers are available - to a process, the list may be reduced. \n Note that the Modern - profile is currently not supported because it is not yet well - adopted by common software libraries." - type: string - enum: - - Old - - Intermediate - - Modern - - Custom - status: - description: status holds observed values from the cluster. They may not - be overridden. - type: object + enum: + - VersionTLS10 + - VersionTLS11 + - VersionTLS12 + - VersionTLS13 + nullable: true + intermediate: + description: "intermediate is a TLS security profile based on: + \n https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29 + \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 + \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 + \ - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 + \ - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 + \ - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 + \ - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 + \ minTLSVersion: TLSv1.2" + type: object + nullable: true + modern: + description: "modern is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility + \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 + \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 + \ minTLSVersion: TLSv1.3 \n NOTE: Currently unsupported." + type: object + nullable: true + old: + description: "old is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility + \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 + \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 + \ - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 + \ - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 + \ - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 + \ - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 + \ - DHE-RSA-CHACHA20-POLY1305 - ECDHE-ECDSA-AES128-SHA256 + \ - ECDHE-RSA-AES128-SHA256 - ECDHE-ECDSA-AES128-SHA + \ - ECDHE-RSA-AES128-SHA - ECDHE-ECDSA-AES256-SHA384 + \ - ECDHE-RSA-AES256-SHA384 - ECDHE-ECDSA-AES256-SHA + \ - ECDHE-RSA-AES256-SHA - DHE-RSA-AES128-SHA256 - + DHE-RSA-AES256-SHA256 - AES128-GCM-SHA256 - AES256-GCM-SHA384 + \ - AES128-SHA256 - AES256-SHA256 - AES128-SHA - + AES256-SHA - DES-CBC3-SHA minTLSVersion: TLSv1.0" + type: object + nullable: true + type: + description: "type is one of Old, Intermediate, Modern or Custom. + Custom provides the ability to specify individual TLS security + profile parameters. Old, Intermediate and Modern are TLS security + profiles based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations + \n The profiles are intent based, so they may change over time + as new ciphers are developed and existing ciphers are found + to be insecure. Depending on precisely which ciphers are available + to a process, the list may be reduced. \n Note that the Modern + profile is currently not supported because it is not yet well + adopted by common software libraries." + type: string + enum: + - Old + - Intermediate + - Modern + - Custom + status: + description: status holds observed values from the cluster. They may not + be overridden. + type: object diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd.yaml index 08aacfeef972..c6de0ac13ab7 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: authentications.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io names: diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_build.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_build.crd.yaml index 9291d837af5d..9bd6113608e5 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_build.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_build.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: builds.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io scope: Cluster @@ -193,7 +195,11 @@ spec: divisor: description: Specifies the output format of the exposed resources, defaults to "1" - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true resource: description: 'Required: resource to select' type: string @@ -292,7 +298,11 @@ spec: resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' type: object additionalProperties: - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true requests: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, @@ -300,7 +310,11 @@ spec: to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' type: object additionalProperties: - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true buildOverrides: description: BuildOverrides controls override settings for builds type: object diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_console.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_console.crd.yaml index b527f7aa32dc..4234d732ec53 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_console.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_console.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: consoles.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: scope: Cluster preserveUnknownFields: false diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns.crd.yaml index c883ee0f0cf3..e864cae7a125 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: dnses.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io names: diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_featuregate.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_featuregate.crd.yaml index 89084a33f571..ec458de32004 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_featuregate.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_featuregate.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: featuregates.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io version: v1 diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml index 8e3200967132..858681c9d864 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: images.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io scope: Cluster diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure.crd.yaml index 2ef761958a50..7287300e4e16 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: infrastructures.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io names: diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_ingress.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_ingress.crd.yaml index ada4404256a3..bd7cdad40ddb 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_ingress.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_ingress.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: ingresses.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io names: diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network.crd.yaml index 958f3b7e24d9..5b029401b093 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: networks.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io names: @@ -60,6 +62,7 @@ spec: type: string hostPrefix: description: The size (prefix) of block to allocate to each node. + If this field is not used by the plugin, it can be left unset. type: integer format: int32 minimum: 0 @@ -132,6 +135,7 @@ spec: type: string hostPrefix: description: The size (prefix) of block to allocate to each node. + If this field is not used by the plugin, it can be left unset. type: integer format: int32 minimum: 0 diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_oauth.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_oauth.crd.yaml index 73a998401109..35388d9c998c 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_oauth.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_oauth.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: oauths.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io names: diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_project.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_project.crd.yaml index a625aa61716b..37541aaed4a0 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_project.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_project.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: projects.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io scope: Cluster diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler.crd.yaml index 7c1ebc34b052..9652bf1f0a70 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: schedulers.config.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: config.openshift.io scope: Cluster diff --git a/vendor/github.com/openshift/api/config/v1/types_apiserver.go b/vendor/github.com/openshift/api/config/v1/types_apiserver.go index 2fffa794b32c..42268db39b53 100644 --- a/vendor/github.com/openshift/api/config/v1/types_apiserver.go +++ b/vendor/github.com/openshift/api/config/v1/types_apiserver.go @@ -51,6 +51,44 @@ type APIServerSpec struct { // is VersionTLS12. // +optional TLSSecurityProfile *TLSSecurityProfile `json:"tlsSecurityProfile,omitempty"` + // audit specifies the settings for audit configuration to be applied to all OpenShift-provided + // API servers in the cluster. + // +optional + // +kubebuilder:default={profile: Default} + Audit Audit `json:"audit"` +} + +// AuditProfileType defines the audit policy profile type. +// +kubebuilder:validation:Enum=Default;WriteRequestBodies;AllRequestBodies +type AuditProfileType string + +const ( + // "Default" is the existing default audit configuration policy. + AuditProfileDefaultType AuditProfileType = "Default" + + // "WriteRequestBodies" is similar to Default but it logs request and response + // HTTP payloads for write requests (create, update, patch) + WriteRequestBodiesAuditProfileType AuditProfileType = "WriteRequestBodies" + + // "AllRequestBodies" is similar to WriteRequestBodies, but also logs request + // and response HTTP payloads for read requests (get, list). + AllRequestBodiesAuditProfileType AuditProfileType = "AllRequestBodies" +) + +type Audit struct { + // profile specifies the name of the desired audit policy configuration to be deployed to + // all OpenShift-provided API servers in the cluster. + // + // The following profiles are provided: + // - Default: the existing default policy. + // - WriteRequestBodies: like 'Default', but logs request and response HTTP payloads for + // write requests (create, update, patch). + // - AllRequestBodies: like 'WriteRequestBodies', but also logs request and response + // HTTP payloads for read requests (get, list). + // + // If unset, the 'Default' profile is used as the default. + // +kubebuilder:default=Default + Profile AuditProfileType `json:"profile,omitempty"` } type APIServerServingCerts struct { diff --git a/vendor/github.com/openshift/api/config/v1/types_cluster_version.go b/vendor/github.com/openshift/api/config/v1/types_cluster_version.go index 771e962add07..58a65228da4e 100644 --- a/vendor/github.com/openshift/api/config/v1/types_cluster_version.go +++ b/vendor/github.com/openshift/api/config/v1/types_cluster_version.go @@ -84,7 +84,7 @@ type ClusterVersionStatus struct { // with the information available, which may be an image or a tag. // +kubebuilder:validation:Required // +required - Desired Update `json:"desired"` + Desired Release `json:"desired"` // history contains a list of the most recent versions applied to the cluster. // This value may be empty during cluster startup, and then will be updated @@ -127,7 +127,7 @@ type ClusterVersionStatus struct { // +nullable // +kubebuilder:validation:Required // +required - AvailableUpdates []Update `json:"availableUpdates"` + AvailableUpdates []Release `json:"availableUpdates"` } // UpdateState is a constant representing whether an update was successfully @@ -221,8 +221,7 @@ type ComponentOverride struct { // URL is a thin wrapper around string that ensures the string is a valid URL. type URL string -// Update represents a release of the ClusterVersionOperator, referenced by the -// Image member. +// Update represents an administrator update request. // +k8s:deepcopy-gen=true type Update struct { // version is a semantic versioning identifying the update version. When this @@ -251,6 +250,34 @@ type Update struct { Force bool `json:"force"` } +// Release represents an OpenShift release image and associated metadata. +// +k8s:deepcopy-gen=true +type Release struct { + // version is a semantic versioning identifying the update version. When this + // field is part of spec, version is optional if image is specified. + // +required + Version string `json:"version"` + + // image is a container image location that contains the update. When this + // field is part of spec, image is optional if version is specified and the + // availableUpdates field contains a matching version. + // +required + Image string `json:"image"` + + // url contains information about this release. This URL is set by + // the 'url' metadata property on a release or the metadata returned by + // the update API and should be displayed as a link in user + // interfaces. The URL field may not be set for test or nightly + // releases. + // +optional + URL URL `json:"url,omitempty"` + + // channels is the set of Cincinnati channels to which the release + // currently belongs. + // +optional + Channels []string `json:"channels,omitempty"` +} + // RetrievedUpdates reports whether available updates have been retrieved from // the upstream update server. The condition is Unknown before retrieval, False // if the updates could not be retrieved or recently failed, or True if the diff --git a/vendor/github.com/openshift/api/config/v1/types_network.go b/vendor/github.com/openshift/api/config/v1/types_network.go index 029ac04910ff..257b54b08d7b 100644 --- a/vendor/github.com/openshift/api/config/v1/types_network.go +++ b/vendor/github.com/openshift/api/config/v1/types_network.go @@ -84,9 +84,11 @@ type ClusterNetworkEntry struct { // The complete block for pod IPs. CIDR string `json:"cidr"` - // The size (prefix) of block to allocate to each node. + // The size (prefix) of block to allocate to each node. If this + // field is not used by the plugin, it can be left unset. // +kubebuilder:validation:Minimum=0 - HostPrefix uint32 `json:"hostPrefix"` + // +optional + HostPrefix uint32 `json:"hostPrefix,omitempty"` } // ExternalIPConfig specifies some IP blocks relevant for the ExternalIP field diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go index 24a4fd27cb1b..7542490ef97f 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go @@ -148,6 +148,7 @@ func (in *APIServerSpec) DeepCopyInto(out *APIServerSpec) { *out = new(TLSSecurityProfile) (*in).DeepCopyInto(*out) } + out.Audit = in.Audit return } @@ -285,6 +286,22 @@ func (in *AdmissionPluginConfig) DeepCopy() *AdmissionPluginConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Audit) DeepCopyInto(out *Audit) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Audit. +func (in *Audit) DeepCopy() *Audit { + if in == nil { + return nil + } + out := new(Audit) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuditConfig) DeepCopyInto(out *AuditConfig) { *out = *in @@ -912,7 +929,7 @@ func (in *ClusterVersionSpec) DeepCopy() *ClusterVersionSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterVersionStatus) DeepCopyInto(out *ClusterVersionStatus) { *out = *in - out.Desired = in.Desired + in.Desired.DeepCopyInto(&out.Desired) if in.History != nil { in, out := &in.History, &out.History *out = make([]UpdateHistory, len(*in)) @@ -929,8 +946,10 @@ func (in *ClusterVersionStatus) DeepCopyInto(out *ClusterVersionStatus) { } if in.AvailableUpdates != nil { in, out := &in.AvailableUpdates, &out.AvailableUpdates - *out = make([]Update, len(*in)) - copy(*out, *in) + *out = make([]Release, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -3239,6 +3258,27 @@ func (in *RegistrySources) DeepCopy() *RegistrySources { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Release) DeepCopyInto(out *Release) { + *out = *in + if in.Channels != nil { + in, out := &in.Channels, &out.Channels + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Release. +func (in *Release) DeepCopy() *Release { + if in == nil { + return nil + } + out := new(Release) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RemoteConnectionInfo) DeepCopyInto(out *RemoteConnectionInfo) { *out = *in diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go index 3730c97d437b..72d3bb2cfd6d 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go @@ -285,12 +285,21 @@ var map_APIServerSpec = map[string]string{ "additionalCORSAllowedOrigins": "additionalCORSAllowedOrigins lists additional, user-defined regular expressions describing hosts for which the API server allows access using the CORS headers. This may be needed to access the API and the integrated OAuth server from JavaScript applications. The values are regular expressions that correspond to the Golang regular expression language.", "encryption": "encryption allows the configuration of encryption of resources at the datastore layer.", "tlsSecurityProfile": "tlsSecurityProfile specifies settings for TLS connections for externally exposed servers.\n\nIf unset, a default (which may change between releases) is chosen. Note that only Old and Intermediate profiles are currently supported, and the maximum available MinTLSVersions is VersionTLS12.", + "audit": "audit specifies the settings for audit configuration to be applied to all OpenShift-provided API servers in the cluster.", } func (APIServerSpec) SwaggerDoc() map[string]string { return map_APIServerSpec } +var map_Audit = map[string]string{ + "profile": "profile specifies the name of the desired audit policy configuration to be deployed to all OpenShift-provided API servers in the cluster.\n\nThe following profiles are provided: - Default: the existing default policy. - WriteRequestBodies: like 'Default', but logs request and response HTTP payloads for write requests (create, update, patch). - AllRequestBodies: like 'WriteRequestBodies', but also logs request and response HTTP payloads for read requests (get, list).\n\nIf unset, the 'Default' profile is used as the default.", +} + +func (Audit) SwaggerDoc() map[string]string { + return map_Audit +} + var map_Authentication = map[string]string{ "": "Authentication specifies cluster-wide settings for authentication (like OAuth and webhook token authenticators). The canonical name of an instance is `cluster`.", "spec": "spec holds user settable values for configuration", @@ -520,8 +529,20 @@ func (ComponentOverride) SwaggerDoc() map[string]string { return map_ComponentOverride } +var map_Release = map[string]string{ + "": "Release represents an OpenShift release image and associated metadata.", + "version": "version is a semantic versioning identifying the update version. When this field is part of spec, version is optional if image is specified.", + "image": "image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version.", + "url": "url contains information about this release. This URL is set by the 'url' metadata property on a release or the metadata returned by the update API and should be displayed as a link in user interfaces. The URL field may not be set for test or nightly releases.", + "channels": "channels is the set of Cincinnati channels to which the release currently belongs.", +} + +func (Release) SwaggerDoc() map[string]string { + return map_Release +} + var map_Update = map[string]string{ - "": "Update represents a release of the ClusterVersionOperator, referenced by the Image member.", + "": "Update represents an administrator update request.", "version": "version is a semantic versioning identifying the update version. When this field is part of spec, version is optional if image is specified.", "image": "image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version.", "force": "force allows an administrator to update to an image that has failed verification, does not appear in the availableUpdates list, or otherwise would be blocked by normal protections on update. This option should only be used when the authenticity of the provided image has been verified out of band because the provided image will run with full administrative access to the cluster. Do not use this flag with images that comes from unknown or potentially malicious sources.\n\nThis flag does not override other forms of consistency checking that are required before a new update is deployed.", @@ -949,7 +970,7 @@ func (IngressSpec) SwaggerDoc() map[string]string { var map_ClusterNetworkEntry = map[string]string{ "": "ClusterNetworkEntry is a contiguous block of IP addresses from which pod IPs are allocated.", "cidr": "The complete block for pod IPs.", - "hostPrefix": "The size (prefix) of block to allocate to each node.", + "hostPrefix": "The size (prefix) of block to allocate to each node. If this field is not used by the plugin, it can be left unset.", } func (ClusterNetworkEntry) SwaggerDoc() map[string]string { diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consoleclidownload.crd.yaml b/vendor/github.com/openshift/api/console/v1/0000_10_consoleclidownload.crd.yaml index 95e45531786c..d5e36cb6f219 100644 --- a/vendor/github.com/openshift/api/console/v1/0000_10_consoleclidownload.crd.yaml +++ b/vendor/github.com/openshift/api/console/v1/0000_10_consoleclidownload.crd.yaml @@ -3,6 +3,7 @@ kind: CustomResourceDefinition metadata: name: consoleclidownloads.console.openshift.io annotations: + include.release.openshift.io/self-managed-high-availability: "true" displayName: ConsoleCLIDownload description: Extension for configuring openshift web console command line interface (CLI) downloads. diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consoleexternalloglink.crd.yaml b/vendor/github.com/openshift/api/console/v1/0000_10_consoleexternalloglink.crd.yaml index a992377a1502..9a31cf92dd37 100644 --- a/vendor/github.com/openshift/api/console/v1/0000_10_consoleexternalloglink.crd.yaml +++ b/vendor/github.com/openshift/api/console/v1/0000_10_consoleexternalloglink.crd.yaml @@ -3,6 +3,7 @@ kind: CustomResourceDefinition metadata: name: consoleexternalloglinks.console.openshift.io annotations: + include.release.openshift.io/self-managed-high-availability: "true" displayName: ConsoleExternalLogLinks description: ConsoleExternalLogLink is an extension for customizing OpenShift web console log links. diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consolelink.crd.yaml b/vendor/github.com/openshift/api/console/v1/0000_10_consolelink.crd.yaml index 20745439b6ff..f62f541f6fbb 100644 --- a/vendor/github.com/openshift/api/console/v1/0000_10_consolelink.crd.yaml +++ b/vendor/github.com/openshift/api/console/v1/0000_10_consolelink.crd.yaml @@ -3,6 +3,7 @@ kind: CustomResourceDefinition metadata: name: consolelinks.console.openshift.io annotations: + include.release.openshift.io/self-managed-high-availability: "true" displayName: ConsoleLinks description: Extension for customizing OpenShift web console links spec: diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consolenotification.crd.yaml b/vendor/github.com/openshift/api/console/v1/0000_10_consolenotification.crd.yaml index 715e0f5013b6..8135b728e008 100644 --- a/vendor/github.com/openshift/api/console/v1/0000_10_consolenotification.crd.yaml +++ b/vendor/github.com/openshift/api/console/v1/0000_10_consolenotification.crd.yaml @@ -3,6 +3,7 @@ kind: CustomResourceDefinition metadata: name: consolenotifications.console.openshift.io annotations: + include.release.openshift.io/self-managed-high-availability: "true" displayName: ConsoleNotification description: Extension for configuring openshift web console notifications. spec: diff --git a/vendor/github.com/openshift/api/console/v1/0000_10_consoleyamlsample.crd.yaml b/vendor/github.com/openshift/api/console/v1/0000_10_consoleyamlsample.crd.yaml index f097466b12d9..e0e3796ea7ac 100644 --- a/vendor/github.com/openshift/api/console/v1/0000_10_consoleyamlsample.crd.yaml +++ b/vendor/github.com/openshift/api/console/v1/0000_10_consoleyamlsample.crd.yaml @@ -3,6 +3,7 @@ kind: CustomResourceDefinition metadata: name: consoleyamlsamples.console.openshift.io annotations: + include.release.openshift.io/self-managed-high-availability: "true" displayName: ConsoleYAMLSample description: Extension for configuring openshift web console YAML samples. spec: diff --git a/vendor/github.com/openshift/api/go.mod b/vendor/github.com/openshift/api/go.mod index dfd595f5f37a..24b746a76f03 100644 --- a/vendor/github.com/openshift/api/go.mod +++ b/vendor/github.com/openshift/api/go.mod @@ -4,11 +4,11 @@ go 1.13 require ( github.com/gogo/protobuf v1.3.1 - github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7 + github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7 github.com/spf13/pflag v1.0.5 - golang.org/x/tools v0.0.0-20200602230032-c00d67ef29d0 - k8s.io/api v0.19.0-rc.2 - k8s.io/apimachinery v0.19.0-rc.2 - k8s.io/code-generator v0.19.0-rc.2 - k8s.io/klog v1.0.0 + golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 + k8s.io/api v0.19.0 + k8s.io/apimachinery v0.19.0 + k8s.io/code-generator v0.19.0 + k8s.io/klog/v2 v2.2.0 ) diff --git a/vendor/github.com/openshift/api/go.sum b/vendor/github.com/openshift/api/go.sum index 485a363e5f27..c4f904ce5729 100644 --- a/vendor/github.com/openshift/api/go.sum +++ b/vendor/github.com/openshift/api/go.sum @@ -20,7 +20,7 @@ github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.0.0-20190815234213-e83c0a1c26c8/go.mod h1:pmLOTb3x90VhIKxsA9yeQG5yfOkkKnkk1h+Ql8NDYDw= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -104,9 +104,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7 h1:iP7TOaN+tEVNUQ0ODEbN1ukjLz918lsIt7Czf8giWlM= -github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7 h1:mOq7Mg1Q9d7nIDxe1SJ6pluMBQsbVxa6olyAGmfYWTg= +github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -119,13 +118,19 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/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= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -135,13 +140,17 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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-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/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/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -164,9 +173,11 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/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-20200602230032-c00d67ef29d0 h1:6txNFSnY+tteYoO+hf01EpdYcYZiurdC9MDIrcUzEu4= -golang.org/x/tools v0.0.0-20200602230032-c00d67ef29d0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 h1:HHeAlu5H9b71C+Fx0K+1dGgVFN1DM1/wz4aoGOA5qS8= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -203,26 +214,23 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.19.0-rc.2 h1:Lq0owhvgpWXmMtz+t2AT/JJpIAPX9X8lK3oE2qslYCU= -k8s.io/api v0.19.0-rc.2/go.mod h1:9nHeM2gbqeaL7yN6UFvOxKzLG5gZ4v+DJ6bpavDetZo= -k8s.io/apimachinery v0.19.0-rc.2 h1:JScnJRuwKHT8RmdrsFMkE4Oi+SVI/QIWFGOOhNZJe/M= -k8s.io/apimachinery v0.19.0-rc.2/go.mod h1:eHbWZVMaaewmYBAUuRYnAmTTMtDhvpPNZuh8/6Yl7v0= -k8s.io/code-generator v0.19.0-rc.2 h1:ZSxniVYeSEv1vry0B2N+yqXAcWTJ4gzmIYadKoPNVFU= -k8s.io/code-generator v0.19.0-rc.2/go.mod h1:uR3gwQvtcOjBrvwXhFF1lw5kq9BOOAfSKl/pZZ1zW3I= +k8s.io/api v0.19.0 h1:XyrFIJqTYZJ2DU7FBE/bSPz7b1HvbVBuBf07oeo6eTc= +k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= +k8s.io/apimachinery v0.19.0 h1:gjKnAda/HZp5k4xQYjL0K/Yb66IvNqjthCb03QlKpaQ= +k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= +k8s.io/code-generator v0.19.0 h1:r0BxYnttP/r8uyKd4+Njg0B57kKi8wLvwEzaaVy3iZ8= +k8s.io/code-generator v0.19.0/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14 h1:t4L10Qfx/p7ASH3gXCdIUtPbbIuegCoUJf3TMSFekjw= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0 h1:Foj74zO6RbjjP4hBEKjnYtjjAhGg4jNynUdYF6fJrok= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/kube-openapi v0.0.0-20200427153329-656914f816f9 h1:5NC2ITmvg8RoxoH0wgmL4zn4VZqXGsKbxrikjaQx6s4= -k8s.io/kube-openapi v0.0.0-20200427153329-656914f816f9/go.mod h1:bfCVj+qXcEaE5SCvzBaqpOySr6tuCcpPKqF6HD8nyCw= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v3 v3.0.1-0.20200706213357-43c19bbb7fba h1:AAbnc5KQuTWKuh2QSnyghKIOTFzB0Jayv7/OFDn3Cy4= -sigs.k8s.io/structured-merge-diff/v3 v3.0.1-0.20200706213357-43c19bbb7fba/go.mod h1:V06abazjHneE37ZdSY/UUwPVgcJMKI/jU5XGUjgIKoc= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= diff --git a/vendor/github.com/openshift/api/helm/install.go b/vendor/github.com/openshift/api/helm/install.go new file mode 100644 index 000000000000..6c8f51892a40 --- /dev/null +++ b/vendor/github.com/openshift/api/helm/install.go @@ -0,0 +1,26 @@ +package helm + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + helmv1beta1 "github.com/openshift/api/helm/v1beta1" +) + +const ( + GroupName = "helm.openshift.io" +) + +var ( + schemeBuilder = runtime.NewSchemeBuilder(helmv1beta1.Install) + // Install is a function which adds every version of this group to a scheme + Install = schemeBuilder.AddToScheme +) + +func Resource(resource string) schema.GroupResource { + return schema.GroupResource{Group: GroupName, Resource: resource} +} + +func Kind(kind string) schema.GroupKind { + return schema.GroupKind{Group: GroupName, Kind: kind} +} diff --git a/vendor/github.com/openshift/api/helm/v1beta1/0000_10-helm-chart-repository.crd.yaml b/vendor/github.com/openshift/api/helm/v1beta1/0000_10-helm-chart-repository.crd.yaml new file mode 100644 index 000000000000..75af27ec29cd --- /dev/null +++ b/vendor/github.com/openshift/api/helm/v1beta1/0000_10-helm-chart-repository.crd.yaml @@ -0,0 +1,169 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: helmchartrepositories.helm.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" +spec: + scope: Cluster + preserveUnknownFields: false + group: helm.openshift.io + names: + kind: HelmChartRepository + listKind: HelmChartRepositoryList + plural: helmchartrepositories + singular: helmchartrepository + versions: + - name: v1beta1 + served: true + storage: true + subresources: + status: {} + "validation": + "openAPIV3Schema": + description: HelmChartRepository holds cluster-wide configuration for proxied + Helm chart repository + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + type: object + properties: + connectionConfig: + description: Required configuration for connecting to the chart repo + type: object + properties: + ca: + description: ca is an optional reference to a config map by name + containing the PEM-encoded CA bundle. It is used as a trust anchor + to validate the TLS certificate presented by the remote server. + The key "ca-bundle.crt" is used to locate the data. If empty, + the default system roots are used. The namespace for this config + map is openshift-config. + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced config + map + type: string + tlsClientConfig: + description: tlsClientConfig is an optional reference to a secret + by name that contains the PEM-encoded TLS client certificate and + private key to present when connecting to the server. The key + "tls.crt" is used to locate the client certificate. The key "tls.key" + is used to locate the private key. The namespace for this secret + is openshift-config. + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced secret + type: string + url: + description: Chart repository URL + type: string + maxLength: 2048 + pattern: ^https?:\/\/ + description: + description: Optional human readable repository description, it can + be used by UI for displaying purposes + type: string + maxLength: 2048 + minLength: 1 + name: + description: Optional associated human readable repository name, it + can be used by UI for displaying purposes + type: string + maxLength: 100 + minLength: 1 + status: + description: Observed status of the repository within the cluster.. + type: object + properties: + conditions: + description: conditions is a list of conditions and their statuses + type: array + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a foo's + current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // + +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + type: object + required: + - lastTransitionTime + - message + - reason + - status + - type + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + type: string + format: date-time + message: + description: message is a human readable message indicating details + about the transition. This may be an empty string. + type: string + maxLength: 32768 + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + type: integer + format: int64 + minimum: 0 + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers of + specific condition types may define expected values and meanings + for this field, and whether the values are considered a guaranteed + API. The value should be a CamelCase string. This field may + not be empty. + type: string + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + status: + description: status of the condition, one of True, False, Unknown. + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + type: string + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ diff --git a/vendor/github.com/openshift/api/helm/v1beta1/doc.go b/vendor/github.com/openshift/api/helm/v1beta1/doc.go new file mode 100644 index 000000000000..8a45cd1c81b2 --- /dev/null +++ b/vendor/github.com/openshift/api/helm/v1beta1/doc.go @@ -0,0 +1,8 @@ +// +k8s:deepcopy-gen=package,register +// +k8s:defaulter-gen=TypeMeta +// +k8s:openapi-gen=true + +// +kubebuilder:validation:Optional +// +groupName=helm.openshift.io +// Package v1 is the v1 version of the API. +package v1beta1 diff --git a/vendor/github.com/openshift/api/helm/v1beta1/register.go b/vendor/github.com/openshift/api/helm/v1beta1/register.go new file mode 100644 index 000000000000..890474569a15 --- /dev/null +++ b/vendor/github.com/openshift/api/helm/v1beta1/register.go @@ -0,0 +1,38 @@ +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + GroupName = "helm.openshift.io" + GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} + schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // Install is a function which adds this version to a scheme + Install = schemeBuilder.AddToScheme + + // SchemeGroupVersion generated code relies on this name + // Deprecated + SchemeGroupVersion = GroupVersion + // AddToScheme exists solely to keep the old generators creating valid code + // DEPRECATED + AddToScheme = schemeBuilder.AddToScheme +) + +// Resource generated code relies on this being here, but it logically belongs to the group +// DEPRECATED +func Resource(resource string) schema.GroupResource { + return schema.GroupResource{Group: GroupName, Resource: resource} +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(GroupVersion, + &HelmChartRepository{}, + &HelmChartRepositoryList{}, + ) + metav1.AddToGroupVersion(scheme, GroupVersion) + return nil +} diff --git a/vendor/github.com/openshift/api/helm/v1beta1/types_helm.go b/vendor/github.com/openshift/api/helm/v1beta1/types_helm.go new file mode 100644 index 000000000000..33613f65cf3e --- /dev/null +++ b/vendor/github.com/openshift/api/helm/v1beta1/types_helm.go @@ -0,0 +1,84 @@ +package v1beta1 + +import ( + configv1 "github.com/openshift/api/config/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:plural=helmchartrepositories + +// HelmChartRepository holds cluster-wide configuration for proxied Helm chart repository +type HelmChartRepository struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // spec holds user settable values for configuration + // +kubebuilder:validation:Required + // +required + Spec HelmChartRepositorySpec `json:"spec"` + + // Observed status of the repository within the cluster.. + // +optional + Status HelmChartRepositoryStatus `json:"status"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type HelmChartRepositoryList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []HelmChartRepository `json:"items"` +} + +// Helm chart repository exposed within the cluster +type HelmChartRepositorySpec struct { + + // Optional associated human readable repository name, it can be used by UI for displaying purposes + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=100 + // +optional + DisplayName string `json:"name,omitempty"` + + // Optional human readable repository description, it can be used by UI for displaying purposes + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +optional + Description string `json:"description,omitempty"` + + // Required configuration for connecting to the chart repo + ConnectionConfig ConnectionConfig `json:"connectionConfig"` +} + +type ConnectionConfig struct { + + // Chart repository URL + // +kubebuilder:validation:Pattern=`^https?:\/\/` + // +kubebuilder:validation:MaxLength=2048 + URL string `json:"url"` + + // ca is an optional reference to a config map by name containing the PEM-encoded CA bundle. + // It is used as a trust anchor to validate the TLS certificate presented by the remote server. + // The key "ca-bundle.crt" is used to locate the data. + // If empty, the default system roots are used. + // The namespace for this config map is openshift-config. + // +optional + CA configv1.ConfigMapNameReference `json:"ca,omitempty"` + + // tlsClientConfig is an optional reference to a secret by name that contains the + // PEM-encoded TLS client certificate and private key to present when connecting to the server. + // The key "tls.crt" is used to locate the client certificate. + // The key "tls.key" is used to locate the private key. + // The namespace for this secret is openshift-config. + // +optional + TLSClientConfig configv1.SecretNameReference `json:"tlsClientConfig,omitempty"` +} + +type HelmChartRepositoryStatus struct { + + // conditions is a list of conditions and their statuses + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` +} diff --git a/vendor/github.com/openshift/api/helm/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/helm/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 000000000000..bf7df6c8fc00 --- /dev/null +++ b/vendor/github.com/openshift/api/helm/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,129 @@ +// +build !ignore_autogenerated + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionConfig) DeepCopyInto(out *ConnectionConfig) { + *out = *in + out.CA = in.CA + out.TLSClientConfig = in.TLSClientConfig + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionConfig. +func (in *ConnectionConfig) DeepCopy() *ConnectionConfig { + if in == nil { + return nil + } + out := new(ConnectionConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HelmChartRepository) DeepCopyInto(out *HelmChartRepository) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartRepository. +func (in *HelmChartRepository) DeepCopy() *HelmChartRepository { + if in == nil { + return nil + } + out := new(HelmChartRepository) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HelmChartRepository) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HelmChartRepositoryList) DeepCopyInto(out *HelmChartRepositoryList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]HelmChartRepository, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartRepositoryList. +func (in *HelmChartRepositoryList) DeepCopy() *HelmChartRepositoryList { + if in == nil { + return nil + } + out := new(HelmChartRepositoryList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HelmChartRepositoryList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HelmChartRepositorySpec) DeepCopyInto(out *HelmChartRepositorySpec) { + *out = *in + out.ConnectionConfig = in.ConnectionConfig + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartRepositorySpec. +func (in *HelmChartRepositorySpec) DeepCopy() *HelmChartRepositorySpec { + if in == nil { + return nil + } + out := new(HelmChartRepositorySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HelmChartRepositoryStatus) DeepCopyInto(out *HelmChartRepositoryStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartRepositoryStatus. +func (in *HelmChartRepositoryStatus) DeepCopy() *HelmChartRepositoryStatus { + if in == nil { + return nil + } + out := new(HelmChartRepositoryStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/openshift/api/imageregistry/v1/00-crd.yaml b/vendor/github.com/openshift/api/imageregistry/v1/00-crd.yaml index 5e578c10a038..14297e9ac329 100644 --- a/vendor/github.com/openshift/api/imageregistry/v1/00-crd.yaml +++ b/vendor/github.com/openshift/api/imageregistry/v1/00-crd.yaml @@ -1,1214 +1,1290 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: configs.imageregistry.operator.openshift.io spec: group: imageregistry.operator.openshift.io scope: Cluster - version: v1 - names: - kind: Config - listKind: ConfigList - plural: configs - singular: config - preserveUnknownFields: false - subresources: - status: {} - validation: - openAPIV3Schema: - description: Config is the configuration object for a registry instance managed - by the registry operator - type: object - required: - - metadata - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ImageRegistrySpec defines the specs for the running registry. - type: object - required: - - logging - - managementState - - replicas - properties: - affinity: - description: affinity is a group of node affinity scheduling rules for - the image registry pod(s). - type: object - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for the pod. - type: object - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to nodes - that satisfy the affinity expressions specified by this field, - but it may choose a node that violates one or more of the - expressions. The node that is most preferred is the one with - the greatest sum of weights, i.e. for each node that meets - all of the scheduling requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to the sum - if the node matches the corresponding matchExpressions; the - node(s) with the highest sum are the most preferred. - type: array - items: - description: An empty preferred scheduling term matches all - objects with implicit weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches no objects (i.e. is also - a no-op). - type: object - required: - - preference - - weight - properties: - preference: - description: A node selector term, associated with the - corresponding weight. - type: object - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - type: array - items: - description: A node selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: An array of string values. If the - operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be - empty. If the operator is Gt or Lt, the values - array must have a single element, which will - be interpreted as an integer. This array is - replaced during a strategic merge patch. - type: array - items: + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + "schema": + "openAPIV3Schema": + description: Config is the configuration object for a registry instance managed + by the registry operator + type: object + required: + - metadata + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ImageRegistrySpec defines the specs for the running registry. + type: object + required: + - managementState + - replicas + properties: + affinity: + description: affinity is a group of node affinity scheduling rules + for the image registry pod(s). + type: object + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + type: array + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + type: object + required: + - preference + - weight + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + type: object + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + type: array + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector + applies to. type: string - matchFields: - description: A list of node selector requirements - by node's fields. - type: array - items: - description: A node selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: An array of string values. If the - operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be - empty. If the operator is Gt or Lt, the values - array must have a single element, which will - be interpreted as an integer. This array is - replaced during a strategic merge patch. - type: array - items: + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. type: string - weight: - description: Weight associated with matching the corresponding - nodeSelectorTerm, in the range 1-100. - type: integer - format: int32 - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node. - type: object - required: - - nodeSelectorTerms - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. The - terms are ORed. - type: array - items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. - type: object - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - type: array - items: - description: A node selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: An array of string values. If the - operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be - empty. If the operator is Gt or Lt, the values - array must have a single element, which will - be interpreted as an integer. This array is - replaced during a strategic merge patch. - type: array - items: + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements + by node's fields. + type: array + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector + applies to. type: string - matchFields: - description: A list of node selector requirements - by node's fields. - type: array - items: - description: A node selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: An array of string values. If the - operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be - empty. If the operator is Gt or Lt, the values - array must have a single element, which will - be interpreted as an integer. This array is - replaced during a strategic merge patch. - type: array - items: + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. type: string - podAffinity: - description: Describes pod affinity scheduling rules (e.g. co-locate - this pod in the same node, zone, etc. as some other pod(s)). - type: object - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to nodes - that satisfy the affinity expressions specified by this field, - but it may choose a node that violates one or more of the - expressions. The node that is most preferred is the one with - the greatest sum of weights, i.e. for each node that meets - all of the scheduling requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to the sum - if the node has pods which matches the corresponding podAffinityTerm; - the node(s) with the highest sum are the most preferred. - type: array - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + type: array + items: + type: string + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. type: object required: - - podAffinityTerm - - weight + - nodeSelectorTerms properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - type: object - required: - - topologyKey - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - type: array - items: - description: A label selector requirement is - a selector that contains values, a key, and - an operator that relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and DoesNotExist. + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + type: array + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + type: object + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + type: array + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + type: array + items: type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. This array - is replaced during a strategic merge patch. - type: array - items: - type: string - matchLabels: - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". - The requirements are ANDed. + matchFields: + description: A list of node selector requirements + by node's fields. + type: array + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. type: object - additionalProperties: - type: string - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - type: array - items: - type: string - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey matches - that of any node on which any of the selected pods - is running. Empty topologyKey is not allowed. - type: string - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - type: integer - format: int32 - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may or may not - try to eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding to - each podAffinityTerm are intersected, i.e. all terms must - be satisfied. - type: array - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) that - this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of pods - is running - type: object - required: - - topologyKey - properties: - labelSelector: - description: A label query over a set of resources, in - this case pods. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - type: array - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. + required: + - key + - operator + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + type: array + items: + type: string + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. type: object - required: - - key - - operator properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. type: array items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + additionalProperties: type: string - matchLabels: - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - additionalProperties: + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. type: string - namespaces: - description: namespaces specifies which namespaces the - labelSelector applies to (matches against); null or - empty list means "this pod's namespace" - type: array - items: - type: string - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of any - node on which any of the selected pods is running. Empty - topologyKey is not allowed. - type: string - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules (e.g. - avoid putting this pod in the same node, zone, etc. as some other - pod(s)). - type: object - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to nodes - that satisfy the anti-affinity expressions specified by this - field, but it may choose a node that violates one or more - of the expressions. The node that is most preferred is the - one with the greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource request, - requiredDuringScheduling anti-affinity expressions, etc.), - compute a sum by iterating through the elements of this field - and adding "weight" to the sum if the node has pods which - matches the corresponding podAffinityTerm; the node(s) with - the highest sum are the most preferred. - type: array - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) - type: object - required: - - podAffinityTerm - - weight - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - type: object - required: - - topologyKey - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - type: array - items: - description: A label selector requirement is - a selector that contains values, a key, and - an operator that relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. This array - is replaced during a strategic merge patch. - type: array - items: - type: string - matchLabels: - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". - The requirements are ANDed. + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. type: object - additionalProperties: - type: string - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - type: array - items: - type: string - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey matches - that of any node on which any of the selected pods - is running. Empty topologyKey is not allowed. + required: + - key + - operator + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies which namespaces the + labelSelector applies to (matches against); null or + empty list means "this pod's namespace" + type: array + items: type: string - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - type: integer - format: int32 - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified by - this field are not met at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity requirements - specified by this field cease to be met at some point during - pod execution (e.g. due to a pod label update), the system - may or may not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all terms must - be satisfied. - type: array - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) that - this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of pods - is running - type: object - required: - - topologyKey - properties: - labelSelector: - description: A label query over a set of resources, in - this case pods. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - type: array - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. type: object - required: - - key - - operator properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. type: array items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + additionalProperties: type: string - matchLabels: - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - additionalProperties: + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. type: string - namespaces: - description: namespaces specifies which namespaces the - labelSelector applies to (matches against); null or - empty list means "this pod's namespace" - type: array - items: - type: string - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of any - node on which any of the selected pods is running. Empty - topologyKey is not allowed. - type: string - defaultRoute: - description: defaultRoute indicates whether an external facing route - for the registry should be created using the default generated hostname. - type: boolean - disableRedirect: - description: disableRedirect controls whether to route all data through - the Registry, rather than redirecting to the backend. - type: boolean - httpSecret: - description: httpSecret is the value needed by the registry to secure - uploads, generated by default. - type: string - logging: - description: logging determines the level of logging enabled in the - registry. - type: integer - format: int64 - managementState: - description: managementState indicates whether the registry instance - represented by this config instance is under operator management or - not. Valid values are Managed, Unmanaged, and Removed. - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - nodeSelector: - description: nodeSelector defines the node selection constraints for - the registry pod. - type: object - additionalProperties: - type: string - proxy: - description: proxy defines the proxy to be used when calling master - api, upstream registries, etc. - type: object - properties: - http: - description: http defines the proxy to be used by the image registry - when accessing HTTP endpoints. - type: string - https: - description: https defines the proxy to be used by the image registry - when accessing HTTPS endpoints. - type: string - noProxy: - description: noProxy defines a comma-separated list of host names - that shouldn't go through any proxy. - type: string - readOnly: - description: readOnly indicates whether the registry instance should - reject attempts to push new images or delete existing ones. - type: boolean - replicas: - description: replicas determines the number of registry instances to - run. - type: integer - format: int32 - requests: - description: requests controls how many parallel requests a given registry - instance will handle before queuing additional requests. - type: object - properties: - read: - description: read defines limits for image registry's reads. - type: object - properties: - maxInQueue: - description: maxInQueue sets the maximum queued api requests - to the registry. - type: integer - maxRunning: - description: maxRunning sets the maximum in flight api requests - to the registry. - type: integer - maxWaitInQueue: - description: maxWaitInQueue sets the maximum time a request - can wait in the queue before being rejected. - type: string - format: duration - write: - description: write defines limits for image registry's writes. - type: object - properties: - maxInQueue: - description: maxInQueue sets the maximum queued api requests - to the registry. - type: integer - maxRunning: - description: maxRunning sets the maximum in flight api requests - to the registry. - type: integer - maxWaitInQueue: - description: maxWaitInQueue sets the maximum time a request - can wait in the queue before being rejected. - type: string - format: duration - resources: - description: resources defines the resource requests+limits for the - registry pod. - type: object - properties: - limits: - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - additionalProperties: - type: string - requests: - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - additionalProperties: - type: string - rolloutStrategy: - description: rolloutStrategy defines rollout strategy for the image - registry deployment. - type: string - pattern: ^(RollingUpdate|Recreate)$ - routes: - description: routes defines additional external facing routes which - should be created for the registry. - type: array - items: - description: ImageRegistryConfigRoute holds information on external - route access to image registry. - type: object - required: - - name - properties: - hostname: - description: hostname for the route. - type: string - name: - description: name of the route to be created. - type: string - secretName: - description: secretName points to secret containing the certificates - to be used by the route. - type: string - storage: - description: storage details for configuring registry storage, e.g. - S3 bucket coordinates. - type: object - properties: - azure: - description: azure represents configuration that uses Azure Blob - Storage. - type: object - properties: - accountName: - description: accountName defines the account to be used by the - registry. - type: string - cloudName: - description: cloudName is the name of the Azure cloud environment - to be used by the registry. If empty, the operator will set - it based on the infrastructure object. - type: string - container: - description: container defines Azure's container to be used - by registry. - type: string - maxLength: 63 - minLength: 3 - pattern: ^[0-9a-z]+(-[0-9a-z]+)*$ - emptyDir: - description: 'emptyDir represents ephemeral storage on the pod''s - host node. WARNING: this storage cannot be used with more than - 1 replica and is not suitable for production use. When the pod - is removed from a node for any reason, the data in the emptyDir - is deleted forever.' - type: object - gcs: - description: gcs represents configuration that uses Google Cloud - Storage. - type: object - properties: - bucket: - description: bucket is the bucket name in which you want to - store the registry's data. Optional, will be generated if - not provided. - type: string - keyID: - description: keyID is the KMS key ID to use for encryption. - Optional, buckets are encrypted by default on GCP. This allows - for the use of a custom encryption key. - type: string - projectID: - description: projectID is the Project ID of the GCP project - that this bucket should be associated with. - type: string - region: - description: region is the GCS location in which your bucket - exists. Optional, will be set based on the installed GCS Region. - type: string - pvc: - description: pvc represents configuration that uses a PersistentVolumeClaim. - type: object - properties: - claim: - description: claim defines the Persisent Volume Claim's name - to be used. - type: string - s3: - description: s3 represents configuration that uses Amazon Simple - Storage Service. - type: object - properties: - bucket: - description: bucket is the bucket name in which you want to - store the registry's data. Optional, will be generated if - not provided. - type: string - cloudFront: - description: cloudFront configures Amazon Cloudfront as the - storage middleware in a registry. - type: object - required: - - baseURL - - keypairID - - privateKey - properties: - baseURL: - description: baseURL contains the SCHEME://HOST[/PATH] at - which Cloudfront is served. - type: string - duration: - description: duration is the duration of the Cloudfront - session. - type: string - format: duration - keypairID: - description: keypairID is key pair ID provided by AWS. - type: string - privateKey: - description: privateKey points to secret containing the - private key, provided by AWS. + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running type: object required: - - key + - topologyKey properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + labelSelector: + description: A label query over a set of resources, + in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies which namespaces the + labelSelector applies to (matches against); null or + empty list means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - encrypt: - description: encrypt specifies whether the registry stores the - image in encrypted format or not. Optional, defaults to false. - type: boolean - keyID: - description: keyID is the KMS key ID to use for encryption. - Optional, Encrypt must be true, or this parameter is ignored. - type: string - region: - description: region is the AWS region in which your bucket exists. - Optional, will be set based on the installed AWS Region. - type: string - regionEndpoint: - description: regionEndpoint is the endpoint for S3 compatible - storage services. Optional, defaults based on the Region that - is provided. - type: string - virtualHostedStyle: - description: virtualHostedStyle enables using S3 virtual hosted - style bucket paths with a custom RegionEndpoint Optional, - defaults to false. - type: boolean - swift: - description: swift represents configuration that uses OpenStack - Object Storage. - type: object - properties: - authURL: - description: authURL defines the URL for obtaining an authentication - token. - type: string - authVersion: - description: authVersion specifies the OpenStack Auth's version. - type: string - container: - description: container defines the name of Swift container where - to store the registry's data. - type: string - domain: - description: domain specifies Openstack's domain name for Identity - v3 API. - type: string - domainID: - description: domainID specifies Openstack's domain id for Identity - v3 API. - type: string - regionName: - description: regionName defines Openstack's region in which - container exists. - type: string - tenant: - description: tenant defines Openstack tenant name to be used - by registry. - type: string - tenantID: - description: tenant defines Openstack tenant id to be used by - registry. - type: string - tolerations: - description: tolerations defines the tolerations for the registry pod. - type: array - items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . + defaultRoute: + description: defaultRoute indicates whether an external facing route + for the registry should be created using the default generated hostname. + type: boolean + disableRedirect: + description: disableRedirect controls whether to route all data through + the Registry, rather than redirecting to the backend. + type: boolean + httpSecret: + description: httpSecret is the value needed by the registry to secure + uploads, generated by default. + type: string + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + logging: + description: logging is deprecated, use logLevel instead. + type: integer + format: int64 + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + nodeSelector: + description: nodeSelector defines the node selection constraints for + the registry pod. + type: object + additionalProperties: + type: string + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + type: object + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + proxy: + description: proxy defines the proxy to be used when calling master + api, upstream registries, etc. type: object properties: - effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, operator - must be Exists; this combination means to match all values and - all keys. + http: + description: http defines the proxy to be used by the image registry + when accessing HTTP endpoints. type: string - operator: - description: Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. Exists - is equivalent to wildcard for value, so that a pod can tolerate - all taints of a particular category. + https: + description: https defines the proxy to be used by the image registry + when accessing HTTPS endpoints. type: string - tolerationSeconds: - description: TolerationSeconds represents the period of time the - toleration (which must be of effect NoExecute, otherwise this - field is ignored) tolerates the taint. By default, it is not - set, which means tolerate the taint forever (do not evict). - Zero and negative values will be treated as 0 (evict immediately) - by the system. - type: integer - format: int64 - value: - description: Value is the taint value the toleration matches to. - If the operator is Exists, the value should be empty, otherwise - just a regular string. + noProxy: + description: noProxy defines a comma-separated list of host names + that shouldn't go through any proxy. type: string - status: - description: ImageRegistryStatus reports image registry operational status. - type: object - required: - - storage - - storageManaged - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + readOnly: + description: readOnly indicates whether the registry instance should + reject attempts to push new images or delete existing ones. + type: boolean + replicas: + description: replicas determines the number of registry instances + to run. + type: integer + format: int32 + requests: + description: requests controls how many parallel requests a given + registry instance will handle before queuing additional requests. type: object properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + read: + description: read defines limits for image registry's reads. + type: object + properties: + maxInQueue: + description: maxInQueue sets the maximum queued api requests + to the registry. + type: integer + maxRunning: + description: maxRunning sets the maximum in flight api requests + to the registry. + type: integer + maxWaitInQueue: + description: maxWaitInQueue sets the maximum time a request + can wait in the queue before being rejected. + type: string + format: duration + write: + description: write defines limits for image registry's writes. + type: object + properties: + maxInQueue: + description: maxInQueue sets the maximum queued api requests + to the registry. + type: integer + maxRunning: + description: maxRunning sets the maximum in flight api requests + to the registry. + type: integer + maxWaitInQueue: + description: maxWaitInQueue sets the maximum time a request + can wait in the queue before being rejected. + type: string + format: duration + resources: + description: resources defines the resource requests+limits for the + registry pod. type: object properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - storage: - description: storage indicates the current applied storage configuration - of the registry. - type: object - properties: - azure: - description: azure represents configuration that uses Azure Blob - Storage. + limits: + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + additionalProperties: + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + requests: + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + additionalProperties: + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + rolloutStrategy: + description: rolloutStrategy defines rollout strategy for the image + registry deployment. + type: string + pattern: ^(RollingUpdate|Recreate)$ + routes: + description: routes defines additional external facing routes which + should be created for the registry. + type: array + items: + description: ImageRegistryConfigRoute holds information on external + route access to image registry. type: object + required: + - name properties: - accountName: - description: accountName defines the account to be used by the - registry. + hostname: + description: hostname for the route. type: string - cloudName: - description: cloudName is the name of the Azure cloud environment - to be used by the registry. If empty, the operator will set - it based on the infrastructure object. + name: + description: name of the route to be created. type: string - container: - description: container defines Azure's container to be used - by registry. + secretName: + description: secretName points to secret containing the certificates + to be used by the route. type: string - maxLength: 63 - minLength: 3 - pattern: ^[0-9a-z]+(-[0-9a-z]+)*$ - emptyDir: - description: 'emptyDir represents ephemeral storage on the pod''s - host node. WARNING: this storage cannot be used with more than - 1 replica and is not suitable for production use. When the pod - is removed from a node for any reason, the data in the emptyDir - is deleted forever.' - type: object - gcs: - description: gcs represents configuration that uses Google Cloud - Storage. + storage: + description: storage details for configuring registry storage, e.g. + S3 bucket coordinates. + type: object + properties: + azure: + description: azure represents configuration that uses Azure Blob + Storage. + type: object + properties: + accountName: + description: accountName defines the account to be used by + the registry. + type: string + cloudName: + description: cloudName is the name of the Azure cloud environment + to be used by the registry. If empty, the operator will + set it based on the infrastructure object. + type: string + container: + description: container defines Azure's container to be used + by registry. + type: string + maxLength: 63 + minLength: 3 + pattern: ^[0-9a-z]+(-[0-9a-z]+)*$ + emptyDir: + description: 'emptyDir represents ephemeral storage on the pod''s + host node. WARNING: this storage cannot be used with more than + 1 replica and is not suitable for production use. When the pod + is removed from a node for any reason, the data in the emptyDir + is deleted forever.' + type: object + gcs: + description: gcs represents configuration that uses Google Cloud + Storage. + type: object + properties: + bucket: + description: bucket is the bucket name in which you want to + store the registry's data. Optional, will be generated if + not provided. + type: string + keyID: + description: keyID is the KMS key ID to use for encryption. + Optional, buckets are encrypted by default on GCP. This + allows for the use of a custom encryption key. + type: string + projectID: + description: projectID is the Project ID of the GCP project + that this bucket should be associated with. + type: string + region: + description: region is the GCS location in which your bucket + exists. Optional, will be set based on the installed GCS + Region. + type: string + managementState: + description: managementState indicates if the operator manages + the underlying storage unit. If Managed the operator will remove + the storage when this operator gets Removed. + type: string + pattern: ^(Managed|Unmanaged)$ + pvc: + description: pvc represents configuration that uses a PersistentVolumeClaim. + type: object + properties: + claim: + description: claim defines the Persisent Volume Claim's name + to be used. + type: string + s3: + description: s3 represents configuration that uses Amazon Simple + Storage Service. + type: object + properties: + bucket: + description: bucket is the bucket name in which you want to + store the registry's data. Optional, will be generated if + not provided. + type: string + cloudFront: + description: cloudFront configures Amazon Cloudfront as the + storage middleware in a registry. + type: object + required: + - baseURL + - keypairID + - privateKey + properties: + baseURL: + description: baseURL contains the SCHEME://HOST[/PATH] + at which Cloudfront is served. + type: string + duration: + description: duration is the duration of the Cloudfront + session. + type: string + format: duration + keypairID: + description: keypairID is key pair ID provided by AWS. + type: string + privateKey: + description: privateKey points to secret containing the + private key, provided by AWS. + type: object + required: + - key + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + encrypt: + description: encrypt specifies whether the registry stores + the image in encrypted format or not. Optional, defaults + to false. + type: boolean + keyID: + description: keyID is the KMS key ID to use for encryption. + Optional, Encrypt must be true, or this parameter is ignored. + type: string + region: + description: region is the AWS region in which your bucket + exists. Optional, will be set based on the installed AWS + Region. + type: string + regionEndpoint: + description: regionEndpoint is the endpoint for S3 compatible + storage services. Optional, defaults based on the Region + that is provided. + type: string + virtualHostedStyle: + description: virtualHostedStyle enables using S3 virtual hosted + style bucket paths with a custom RegionEndpoint Optional, + defaults to false. + type: boolean + swift: + description: swift represents configuration that uses OpenStack + Object Storage. + type: object + properties: + authURL: + description: authURL defines the URL for obtaining an authentication + token. + type: string + authVersion: + description: authVersion specifies the OpenStack Auth's version. + type: string + container: + description: container defines the name of Swift container + where to store the registry's data. + type: string + domain: + description: domain specifies Openstack's domain name for + Identity v3 API. + type: string + domainID: + description: domainID specifies Openstack's domain id for + Identity v3 API. + type: string + regionName: + description: regionName defines Openstack's region in which + container exists. + type: string + tenant: + description: tenant defines Openstack tenant name to be used + by registry. + type: string + tenantID: + description: tenant defines Openstack tenant id to be used + by registry. + type: string + tolerations: + description: tolerations defines the tolerations for the registry + pod. + type: array + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . type: object properties: - bucket: - description: bucket is the bucket name in which you want to - store the registry's data. Optional, will be generated if - not provided. + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. type: string - keyID: - description: keyID is the KMS key ID to use for encryption. - Optional, buckets are encrypted by default on GCP. This allows - for the use of a custom encryption key. + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. type: string - projectID: - description: projectID is the Project ID of the GCP project - that this bucket should be associated with. + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. type: string - region: - description: region is the GCS location in which your bucket - exists. Optional, will be set based on the installed GCS Region. + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + type: integer + format: int64 + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. type: string - pvc: - description: pvc represents configuration that uses a PersistentVolumeClaim. + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' + type: object + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + description: ImageRegistryStatus reports image registry operational status. + type: object + required: + - storage + - storageManaged + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. type: object properties: - claim: - description: claim defines the Persisent Volume Claim's name - to be used. + lastTransitionTime: type: string - s3: - description: s3 represents configuration that uses Amazon Simple - Storage Service. - type: object - properties: - bucket: - description: bucket is the bucket name in which you want to - store the registry's data. Optional, will be generated if - not provided. + format: date-time + message: type: string - cloudFront: - description: cloudFront configures Amazon Cloudfront as the - storage middleware in a registry. - type: object - required: - - baseURL - - keypairID - - privateKey - properties: - baseURL: - description: baseURL contains the SCHEME://HOST[/PATH] at - which Cloudfront is served. - type: string - duration: - description: duration is the duration of the Cloudfront - session. - type: string - format: duration - keypairID: - description: keypairID is key pair ID provided by AWS. - type: string - privateKey: - description: privateKey points to secret containing the - private key, provided by AWS. - type: object - required: - - key - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - encrypt: - description: encrypt specifies whether the registry stores the - image in encrypted format or not. Optional, defaults to false. - type: boolean - keyID: - description: keyID is the KMS key ID to use for encryption. - Optional, Encrypt must be true, or this parameter is ignored. + reason: type: string - region: - description: region is the AWS region in which your bucket exists. - Optional, will be set based on the installed AWS Region. + status: type: string - regionEndpoint: - description: regionEndpoint is the endpoint for S3 compatible - storage services. Optional, defaults based on the Region that - is provided. + type: type: string - virtualHostedStyle: - description: virtualHostedStyle enables using S3 virtual hosted - style bucket paths with a custom RegionEndpoint Optional, - defaults to false. - type: boolean - swift: - description: swift represents configuration that uses OpenStack - Object Storage. + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. type: object properties: - authURL: - description: authURL defines the URL for obtaining an authentication - token. - type: string - authVersion: - description: authVersion specifies the OpenStack Auth's version. - type: string - container: - description: container defines the name of Swift container where - to store the registry's data. - type: string - domain: - description: domain specifies Openstack's domain name for Identity - v3 API. + group: + description: group is the group of the thing you're tracking type: string - domainID: - description: domainID specifies Openstack's domain id for Identity - v3 API. + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps type: string - regionName: - description: regionName defines Openstack's region in which - container exists. + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking type: string - tenant: - description: tenant defines Openstack tenant name to be used - by registry. + namespace: + description: namespace is where the thing you're tracking is type: string - tenantID: - description: tenant defines Openstack tenant id to be used by - registry. + resource: + description: resource is the resource type of the thing you're + tracking type: string - storageManaged: - description: storageManaged is a boolean which denotes whether or not - we created the registry storage medium (such as an S3 bucket). - type: boolean - version: - description: version is the level this availability applies to - type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + storage: + description: storage indicates the current applied storage configuration + of the registry. + type: object + properties: + azure: + description: azure represents configuration that uses Azure Blob + Storage. + type: object + properties: + accountName: + description: accountName defines the account to be used by + the registry. + type: string + cloudName: + description: cloudName is the name of the Azure cloud environment + to be used by the registry. If empty, the operator will + set it based on the infrastructure object. + type: string + container: + description: container defines Azure's container to be used + by registry. + type: string + maxLength: 63 + minLength: 3 + pattern: ^[0-9a-z]+(-[0-9a-z]+)*$ + emptyDir: + description: 'emptyDir represents ephemeral storage on the pod''s + host node. WARNING: this storage cannot be used with more than + 1 replica and is not suitable for production use. When the pod + is removed from a node for any reason, the data in the emptyDir + is deleted forever.' + type: object + gcs: + description: gcs represents configuration that uses Google Cloud + Storage. + type: object + properties: + bucket: + description: bucket is the bucket name in which you want to + store the registry's data. Optional, will be generated if + not provided. + type: string + keyID: + description: keyID is the KMS key ID to use for encryption. + Optional, buckets are encrypted by default on GCP. This + allows for the use of a custom encryption key. + type: string + projectID: + description: projectID is the Project ID of the GCP project + that this bucket should be associated with. + type: string + region: + description: region is the GCS location in which your bucket + exists. Optional, will be set based on the installed GCS + Region. + type: string + managementState: + description: managementState indicates if the operator manages + the underlying storage unit. If Managed the operator will remove + the storage when this operator gets Removed. + type: string + pattern: ^(Managed|Unmanaged)$ + pvc: + description: pvc represents configuration that uses a PersistentVolumeClaim. + type: object + properties: + claim: + description: claim defines the Persisent Volume Claim's name + to be used. + type: string + s3: + description: s3 represents configuration that uses Amazon Simple + Storage Service. + type: object + properties: + bucket: + description: bucket is the bucket name in which you want to + store the registry's data. Optional, will be generated if + not provided. + type: string + cloudFront: + description: cloudFront configures Amazon Cloudfront as the + storage middleware in a registry. + type: object + required: + - baseURL + - keypairID + - privateKey + properties: + baseURL: + description: baseURL contains the SCHEME://HOST[/PATH] + at which Cloudfront is served. + type: string + duration: + description: duration is the duration of the Cloudfront + session. + type: string + format: duration + keypairID: + description: keypairID is key pair ID provided by AWS. + type: string + privateKey: + description: privateKey points to secret containing the + private key, provided by AWS. + type: object + required: + - key + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + encrypt: + description: encrypt specifies whether the registry stores + the image in encrypted format or not. Optional, defaults + to false. + type: boolean + keyID: + description: keyID is the KMS key ID to use for encryption. + Optional, Encrypt must be true, or this parameter is ignored. + type: string + region: + description: region is the AWS region in which your bucket + exists. Optional, will be set based on the installed AWS + Region. + type: string + regionEndpoint: + description: regionEndpoint is the endpoint for S3 compatible + storage services. Optional, defaults based on the Region + that is provided. + type: string + virtualHostedStyle: + description: virtualHostedStyle enables using S3 virtual hosted + style bucket paths with a custom RegionEndpoint Optional, + defaults to false. + type: boolean + swift: + description: swift represents configuration that uses OpenStack + Object Storage. + type: object + properties: + authURL: + description: authURL defines the URL for obtaining an authentication + token. + type: string + authVersion: + description: authVersion specifies the OpenStack Auth's version. + type: string + container: + description: container defines the name of Swift container + where to store the registry's data. + type: string + domain: + description: domain specifies Openstack's domain name for + Identity v3 API. + type: string + domainID: + description: domainID specifies Openstack's domain id for + Identity v3 API. + type: string + regionName: + description: regionName defines Openstack's region in which + container exists. + type: string + tenant: + description: tenant defines Openstack tenant name to be used + by registry. + type: string + tenantID: + description: tenant defines Openstack tenant id to be used + by registry. + type: string + storageManaged: + description: storageManaged is deprecated, please refer to Storage.managementState + type: boolean + version: + description: version is the level this availability applies to + type: string + names: + kind: Config + listKind: ConfigList + plural: configs + singular: config diff --git a/vendor/github.com/openshift/api/imageregistry/v1/01-crd.yaml b/vendor/github.com/openshift/api/imageregistry/v1/01-crd.yaml index 8cf042d36263..a1f7cce99e6b 100644 --- a/vendor/github.com/openshift/api/imageregistry/v1/01-crd.yaml +++ b/vendor/github.com/openshift/api/imageregistry/v1/01-crd.yaml @@ -1,744 +1,778 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: imagepruners.imageregistry.operator.openshift.io spec: group: imageregistry.operator.openshift.io scope: Cluster - version: v1 - preserveUnknownFields: false - subresources: - status: {} - names: - kind: ImagePruner - listKind: ImagePrunerList - plural: imagepruners - singular: imagepruner - "validation": - "openAPIV3Schema": - description: ImagePruner is the configuration object for an image registry pruner - managed by the registry operator. - type: object - required: - - metadata - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ImagePrunerSpec defines the specs for the running image pruner. - type: object - properties: - affinity: - description: affinity is a group of node affinity scheduling rules for - the image pruner pod. - type: object - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for the pod. - type: object - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to nodes - that satisfy the affinity expressions specified by this field, - but it may choose a node that violates one or more of the - expressions. The node that is most preferred is the one with - the greatest sum of weights, i.e. for each node that meets - all of the scheduling requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to the sum - if the node matches the corresponding matchExpressions; the - node(s) with the highest sum are the most preferred. - type: array - items: - description: An empty preferred scheduling term matches all - objects with implicit weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches no objects (i.e. is also - a no-op). - type: object - required: - - preference - - weight - properties: - preference: - description: A node selector term, associated with the - corresponding weight. - type: object - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - type: array - items: - description: A node selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: An array of string values. If the - operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be - empty. If the operator is Gt or Lt, the values - array must have a single element, which will - be interpreted as an integer. This array is - replaced during a strategic merge patch. - type: array - items: + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + "schema": + "openAPIV3Schema": + description: ImagePruner is the configuration object for an image registry + pruner managed by the registry operator. + type: object + required: + - metadata + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ImagePrunerSpec defines the specs for the running image pruner. + type: object + properties: + affinity: + description: affinity is a group of node affinity scheduling rules + for the image pruner pod. + type: object + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + type: array + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + type: object + required: + - preference + - weight + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + type: object + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + type: array + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector + applies to. type: string - matchFields: - description: A list of node selector requirements - by node's fields. - type: array - items: - description: A node selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: An array of string values. If the - operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be - empty. If the operator is Gt or Lt, the values - array must have a single element, which will - be interpreted as an integer. This array is - replaced during a strategic merge patch. - type: array - items: + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. type: string - weight: - description: Weight associated with matching the corresponding - nodeSelectorTerm, in the range 1-100. - type: integer - format: int32 - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node. - type: object - required: - - nodeSelectorTerms - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. The - terms are ORed. - type: array - items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. - type: object - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - type: array - items: - description: A node selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: An array of string values. If the - operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be - empty. If the operator is Gt or Lt, the values - array must have a single element, which will - be interpreted as an integer. This array is - replaced during a strategic merge patch. - type: array - items: + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements + by node's fields. + type: array + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector + applies to. type: string - matchFields: - description: A list of node selector requirements - by node's fields. - type: array - items: - description: A node selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists, DoesNotExist. Gt, and Lt. - type: string - values: - description: An array of string values. If the - operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be - empty. If the operator is Gt or Lt, the values - array must have a single element, which will - be interpreted as an integer. This array is - replaced during a strategic merge patch. - type: array - items: + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. type: string - podAffinity: - description: Describes pod affinity scheduling rules (e.g. co-locate - this pod in the same node, zone, etc. as some other pod(s)). - type: object - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to nodes - that satisfy the affinity expressions specified by this field, - but it may choose a node that violates one or more of the - expressions. The node that is most preferred is the one with - the greatest sum of weights, i.e. for each node that meets - all of the scheduling requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to the sum - if the node has pods which matches the corresponding podAffinityTerm; - the node(s) with the highest sum are the most preferred. - type: array - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + type: array + items: + type: string + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. type: object required: - - podAffinityTerm - - weight + - nodeSelectorTerms properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - type: object - required: - - topologyKey - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - type: array - items: - description: A label selector requirement is - a selector that contains values, a key, and - an operator that relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and DoesNotExist. + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + type: array + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + type: object + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + type: array + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + type: array + items: type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. This array - is replaced during a strategic merge patch. - type: array - items: - type: string - matchLabels: - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". - The requirements are ANDed. + matchFields: + description: A list of node selector requirements + by node's fields. + type: array + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. type: object - additionalProperties: - type: string - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - type: array - items: - type: string - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey matches - that of any node on which any of the selected pods - is running. Empty topologyKey is not allowed. - type: string - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - type: integer - format: int32 - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may or may not - try to eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding to - each podAffinityTerm are intersected, i.e. all terms must - be satisfied. - type: array - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) that - this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of pods - is running - type: object - required: - - topologyKey - properties: - labelSelector: - description: A label query over a set of resources, in - this case pods. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - type: array - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. + required: + - key + - operator + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + type: array + items: + type: string + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. type: object - required: - - key - - operator properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. type: array items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + additionalProperties: type: string - matchLabels: - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - additionalProperties: + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. type: string - namespaces: - description: namespaces specifies which namespaces the - labelSelector applies to (matches against); null or - empty list means "this pod's namespace" - type: array - items: - type: string - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of any - node on which any of the selected pods is running. Empty - topologyKey is not allowed. - type: string - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules (e.g. - avoid putting this pod in the same node, zone, etc. as some other - pod(s)). - type: object - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to nodes - that satisfy the anti-affinity expressions specified by this - field, but it may choose a node that violates one or more - of the expressions. The node that is most preferred is the - one with the greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource request, - requiredDuringScheduling anti-affinity expressions, etc.), - compute a sum by iterating through the elements of this field - and adding "weight" to the sum if the node has pods which - matches the corresponding podAffinityTerm; the node(s) with - the highest sum are the most preferred. - type: array - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) - type: object - required: - - podAffinityTerm - - weight - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - type: object - required: - - topologyKey - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - type: array - items: - description: A label selector requirement is - a selector that contains values, a key, and - an operator that relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. This array - is replaced during a strategic merge patch. - type: array - items: - type: string - matchLabels: - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". - The requirements are ANDed. + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. type: object - additionalProperties: - type: string - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - type: array - items: - type: string - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey matches - that of any node on which any of the selected pods - is running. Empty topologyKey is not allowed. + required: + - key + - operator + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies which namespaces the + labelSelector applies to (matches against); null or + empty list means "this pod's namespace" + type: array + items: type: string - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - type: integer - format: int32 - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified by - this field are not met at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity requirements - specified by this field cease to be met at some point during - pod execution (e.g. due to a pod label update), the system - may or may not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all terms must - be satisfied. - type: array - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) that - this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of pods - is running - type: object - required: - - topologyKey - properties: - labelSelector: - description: A label query over a set of resources, in - this case pods. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - type: array - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. type: object - required: - - key - - operator properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. type: array items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + additionalProperties: type: string - matchLabels: - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - additionalProperties: + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. type: string - namespaces: - description: namespaces specifies which namespaces the - labelSelector applies to (matches against); null or - empty list means "this pod's namespace" - type: array - items: + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies which namespaces the + labelSelector applies to (matches against); null or + empty list means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. type: string - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of any - node on which any of the selected pods is running. Empty - topologyKey is not allowed. - type: string - failedJobsHistoryLimit: - description: failedJobsHistoryLimit specifies how many failed image - pruner jobs to retain. Defaults to 3 if not set. - type: integer - format: int32 - keepTagRevisions: - description: keepTagRevisions specifies the number of image revisions - for a tag in an image stream that will be preserved. Defaults to 3. - type: integer - keepYoungerThan: - description: 'keepYoungerThan specifies the minimum age in nanoseconds - of an image and its referrers for it to be considered a candidate - for pruning. DEPRECATED: This field is deprecated in favor of keepYoungerThanDuration. - If both are set, this field is ignored and keepYoungerThanDuration - takes precedence.' - type: integer - format: int64 - keepYoungerThanDuration: - description: keepYoungerThanDuration specifies the minimum age of an - image and its referrers for it to be considered a candidate for pruning. - Defaults to 60m (60 minutes). - type: string - format: duration - nodeSelector: - description: nodeSelector defines the node selection constraints for - the image pruner pod. - type: object - additionalProperties: + failedJobsHistoryLimit: + description: failedJobsHistoryLimit specifies how many failed image + pruner jobs to retain. Defaults to 3 if not set. + type: integer + format: int32 + ignoreInvalidImageReferences: + description: ignoreInvalidImageReferences indicates whether the pruner + can ignore errors while parsing image references. + type: boolean + keepTagRevisions: + description: keepTagRevisions specifies the number of image revisions + for a tag in an image stream that will be preserved. Defaults to + 3. + type: integer + keepYoungerThan: + description: 'keepYoungerThan specifies the minimum age in nanoseconds + of an image and its referrers for it to be considered a candidate + for pruning. DEPRECATED: This field is deprecated in favor of keepYoungerThanDuration. + If both are set, this field is ignored and keepYoungerThanDuration + takes precedence.' + type: integer + format: int64 + keepYoungerThanDuration: + description: keepYoungerThanDuration specifies the minimum age of + an image and its referrers for it to be considered a candidate for + pruning. Defaults to 60m (60 minutes). type: string - resources: - description: resources defines the resource requests and limits for - the image pruner pod. - type: object - properties: - limits: - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - additionalProperties: - type: string - requests: - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - additionalProperties: - type: string - schedule: - description: 'schedule specifies when to execute the job using standard - cronjob syntax: https://wikipedia.org/wiki/Cron. Defaults to `0 0 - * * *`.' - type: string - successfulJobsHistoryLimit: - description: successfulJobsHistoryLimit specifies how many successful - image pruner jobs to retain. Defaults to 3 if not set. - type: integer - format: int32 - suspend: - description: suspend specifies whether or not to suspend subsequent - executions of this cronjob. Defaults to false. - type: boolean - tolerations: - description: tolerations defines the node tolerations for the image - pruner pod. - type: array - items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . + format: duration + nodeSelector: + description: nodeSelector defines the node selection constraints for + the image pruner pod. type: object - properties: - effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, operator - must be Exists; this combination means to match all values and - all keys. - type: string - operator: - description: Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. Exists - is equivalent to wildcard for value, so that a pod can tolerate - all taints of a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of time the - toleration (which must be of effect NoExecute, otherwise this - field is ignored) tolerates the taint. By default, it is not - set, which means tolerate the taint forever (do not evict). - Zero and negative values will be treated as 0 (evict immediately) - by the system. - type: integer - format: int64 - value: - description: Value is the taint value the toleration matches to. - If the operator is Exists, the value should be empty, otherwise - just a regular string. - type: string - status: - description: ImagePrunerStatus reports image pruner operational status. - type: object - properties: - conditions: - description: conditions is a list of conditions and their status. - type: array - items: - description: OperatorCondition is just the standard condition fields. + additionalProperties: + type: string + resources: + description: resources defines the resource requests and limits for + the image pruner pod. type: object properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - observedGeneration: - description: observedGeneration is the last generation change that has - been applied. - type: integer - format: int64 + limits: + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + additionalProperties: + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + requests: + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + additionalProperties: + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + schedule: + description: 'schedule specifies when to execute the job using standard + cronjob syntax: https://wikipedia.org/wiki/Cron. Defaults to `0 + 0 * * *`.' + type: string + successfulJobsHistoryLimit: + description: successfulJobsHistoryLimit specifies how many successful + image pruner jobs to retain. Defaults to 3 if not set. + type: integer + format: int32 + suspend: + description: suspend specifies whether or not to suspend subsequent + executions of this cronjob. Defaults to false. + type: boolean + tolerations: + description: tolerations defines the node tolerations for the image + pruner pod. + type: array + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + type: object + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + type: integer + format: int64 + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + status: + description: ImagePrunerStatus reports image pruner operational status. + type: object + properties: + conditions: + description: conditions is a list of conditions and their status. + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + observedGeneration: + description: observedGeneration is the last generation change that + has been applied. + type: integer + format: int64 + names: + kind: ImagePruner + listKind: ImagePrunerList + plural: imagepruners + singular: imagepruner diff --git a/vendor/github.com/openshift/api/imageregistry/v1/types.go b/vendor/github.com/openshift/api/imageregistry/v1/types.go index 6e84b13be41a..a9988843a40f 100644 --- a/vendor/github.com/openshift/api/imageregistry/v1/types.go +++ b/vendor/github.com/openshift/api/imageregistry/v1/types.go @@ -16,6 +16,14 @@ type ConfigList struct { Items []Config `json:"items"` } +const ( + // StorageManagementStateManaged indicates the operator is managing the underlying storage. + StorageManagementStateManaged = "Managed" + // StorageManagementStateUnmanaged indicates the operator is not managing the underlying + // storage. + StorageManagementStateUnmanaged = "Unmanaged" +) + // +genclient // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -33,6 +41,8 @@ type Config struct { // ImageRegistrySpec defines the specs for the running registry. type ImageRegistrySpec struct { + // operatorSpec allows operator specific configuration to be made. + operatorv1.OperatorSpec `json:",inline"` // managementState indicates whether the registry instance represented // by this config instance is under operator management or not. Valid // values are Managed, Unmanaged, and Removed. @@ -70,8 +80,9 @@ type ImageRegistrySpec struct { Routes []ImageRegistryConfigRoute `json:"routes,omitempty"` // replicas determines the number of registry instances to run. Replicas int32 `json:"replicas"` - // logging determines the level of logging enabled in the registry. - LogLevel int64 `json:"logging"` + // logging is deprecated, use logLevel instead. + // +optional + Logging int64 `json:"logging"` // resources defines the resource requests+limits for the registry pod. // +optional Resources *corev1.ResourceRequirements `json:"resources,omitempty"` @@ -96,9 +107,7 @@ type ImageRegistrySpec struct { type ImageRegistryStatus struct { operatorv1.OperatorStatus `json:",inline"` - // storageManaged is a boolean which denotes whether or not - // we created the registry storage medium (such as an - // S3 bucket). + // storageManaged is deprecated, please refer to Storage.managementState StorageManaged bool `json:"storageManaged"` // storage indicates the current applied storage configuration of the // registry. @@ -283,6 +292,12 @@ type ImageRegistryConfigStorage struct { // azure represents configuration that uses Azure Blob Storage. // +optional Azure *ImageRegistryConfigStorageAzure `json:"azure,omitempty"` + // managementState indicates if the operator manages the underlying + // storage unit. If Managed the operator will remove the storage when + // this operator gets Removed. + // +optional + // +kubebuilder:validation:Pattern=`^(Managed|Unmanaged)$` + ManagementState string `json:"managementState,omitempty"` } // ImageRegistryConfigRequests defines registry limits on requests read and write. diff --git a/vendor/github.com/openshift/api/imageregistry/v1/types_imagepruner.go b/vendor/github.com/openshift/api/imageregistry/v1/types_imagepruner.go index 55360dc6a460..0ed892e009c2 100644 --- a/vendor/github.com/openshift/api/imageregistry/v1/types_imagepruner.go +++ b/vendor/github.com/openshift/api/imageregistry/v1/types_imagepruner.go @@ -76,6 +76,10 @@ type ImagePrunerSpec struct { // Defaults to 3 if not set. // +optional FailedJobsHistoryLimit *int32 `json:"failedJobsHistoryLimit,omitempty"` + // ignoreInvalidImageReferences indicates whether the pruner can ignore + // errors while parsing image references. + // +optional + IgnoreInvalidImageReferences bool `json:"ignoreInvalidImageReferences,omitempty"` } // ImagePrunerStatus reports image pruner operational status. diff --git a/vendor/github.com/openshift/api/imageregistry/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/imageregistry/v1/zz_generated.deepcopy.go index a58aa3bc6dc2..87074c50c07d 100644 --- a/vendor/github.com/openshift/api/imageregistry/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/imageregistry/v1/zz_generated.deepcopy.go @@ -463,6 +463,7 @@ func (in *ImageRegistryConfigStorageSwift) DeepCopy() *ImageRegistryConfigStorag // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImageRegistrySpec) DeepCopyInto(out *ImageRegistrySpec) { *out = *in + in.OperatorSpec.DeepCopyInto(&out.OperatorSpec) out.Proxy = in.Proxy in.Storage.DeepCopyInto(&out.Storage) out.Requests = in.Requests diff --git a/vendor/github.com/openshift/api/imageregistry/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/imageregistry/v1/zz_generated.swagger_doc_generated.go index fae71a443f3c..0084cc3669a0 100644 --- a/vendor/github.com/openshift/api/imageregistry/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/imageregistry/v1/zz_generated.swagger_doc_generated.go @@ -71,13 +71,14 @@ func (ImageRegistryConfigRoute) SwaggerDoc() map[string]string { } var map_ImageRegistryConfigStorage = map[string]string{ - "": "ImageRegistryConfigStorage describes how the storage should be configured for the image registry.", - "emptyDir": "emptyDir represents ephemeral storage on the pod's host node. WARNING: this storage cannot be used with more than 1 replica and is not suitable for production use. When the pod is removed from a node for any reason, the data in the emptyDir is deleted forever.", - "s3": "s3 represents configuration that uses Amazon Simple Storage Service.", - "gcs": "gcs represents configuration that uses Google Cloud Storage.", - "swift": "swift represents configuration that uses OpenStack Object Storage.", - "pvc": "pvc represents configuration that uses a PersistentVolumeClaim.", - "azure": "azure represents configuration that uses Azure Blob Storage.", + "": "ImageRegistryConfigStorage describes how the storage should be configured for the image registry.", + "emptyDir": "emptyDir represents ephemeral storage on the pod's host node. WARNING: this storage cannot be used with more than 1 replica and is not suitable for production use. When the pod is removed from a node for any reason, the data in the emptyDir is deleted forever.", + "s3": "s3 represents configuration that uses Amazon Simple Storage Service.", + "gcs": "gcs represents configuration that uses Google Cloud Storage.", + "swift": "swift represents configuration that uses OpenStack Object Storage.", + "pvc": "pvc represents configuration that uses a PersistentVolumeClaim.", + "azure": "azure represents configuration that uses Azure Blob Storage.", + "managementState": "managementState indicates if the operator manages the underlying storage unit. If Managed the operator will remove the storage when this operator gets Removed.", } func (ImageRegistryConfigStorage) SwaggerDoc() map[string]string { @@ -179,7 +180,7 @@ var map_ImageRegistrySpec = map[string]string{ "defaultRoute": "defaultRoute indicates whether an external facing route for the registry should be created using the default generated hostname.", "routes": "routes defines additional external facing routes which should be created for the registry.", "replicas": "replicas determines the number of registry instances to run.", - "logging": "logging determines the level of logging enabled in the registry.", + "logging": "logging is deprecated, use logLevel instead.", "resources": "resources defines the resource requests+limits for the registry pod.", "nodeSelector": "nodeSelector defines the node selection constraints for the registry pod.", "tolerations": "tolerations defines the tolerations for the registry pod.", @@ -193,7 +194,7 @@ func (ImageRegistrySpec) SwaggerDoc() map[string]string { var map_ImageRegistryStatus = map[string]string{ "": "ImageRegistryStatus reports image registry operational status.", - "storageManaged": "storageManaged is a boolean which denotes whether or not we created the registry storage medium (such as an S3 bucket).", + "storageManaged": "storageManaged is deprecated, please refer to Storage.managementState", "storage": "storage indicates the current applied storage configuration of the registry.", } @@ -218,18 +219,19 @@ func (ImagePrunerList) SwaggerDoc() map[string]string { } var map_ImagePrunerSpec = map[string]string{ - "": "ImagePrunerSpec defines the specs for the running image pruner.", - "schedule": "schedule specifies when to execute the job using standard cronjob syntax: https://wikipedia.org/wiki/Cron. Defaults to `0 0 * * *`.", - "suspend": "suspend specifies whether or not to suspend subsequent executions of this cronjob. Defaults to false.", - "keepTagRevisions": "keepTagRevisions specifies the number of image revisions for a tag in an image stream that will be preserved. Defaults to 3.", - "keepYoungerThan": "keepYoungerThan specifies the minimum age in nanoseconds of an image and its referrers for it to be considered a candidate for pruning. DEPRECATED: This field is deprecated in favor of keepYoungerThanDuration. If both are set, this field is ignored and keepYoungerThanDuration takes precedence.", - "keepYoungerThanDuration": "keepYoungerThanDuration specifies the minimum age of an image and its referrers for it to be considered a candidate for pruning. Defaults to 60m (60 minutes).", - "resources": "resources defines the resource requests and limits for the image pruner pod.", - "affinity": "affinity is a group of node affinity scheduling rules for the image pruner pod.", - "nodeSelector": "nodeSelector defines the node selection constraints for the image pruner pod.", - "tolerations": "tolerations defines the node tolerations for the image pruner pod.", - "successfulJobsHistoryLimit": "successfulJobsHistoryLimit specifies how many successful image pruner jobs to retain. Defaults to 3 if not set.", - "failedJobsHistoryLimit": "failedJobsHistoryLimit specifies how many failed image pruner jobs to retain. Defaults to 3 if not set.", + "": "ImagePrunerSpec defines the specs for the running image pruner.", + "schedule": "schedule specifies when to execute the job using standard cronjob syntax: https://wikipedia.org/wiki/Cron. Defaults to `0 0 * * *`.", + "suspend": "suspend specifies whether or not to suspend subsequent executions of this cronjob. Defaults to false.", + "keepTagRevisions": "keepTagRevisions specifies the number of image revisions for a tag in an image stream that will be preserved. Defaults to 3.", + "keepYoungerThan": "keepYoungerThan specifies the minimum age in nanoseconds of an image and its referrers for it to be considered a candidate for pruning. DEPRECATED: This field is deprecated in favor of keepYoungerThanDuration. If both are set, this field is ignored and keepYoungerThanDuration takes precedence.", + "keepYoungerThanDuration": "keepYoungerThanDuration specifies the minimum age of an image and its referrers for it to be considered a candidate for pruning. Defaults to 60m (60 minutes).", + "resources": "resources defines the resource requests and limits for the image pruner pod.", + "affinity": "affinity is a group of node affinity scheduling rules for the image pruner pod.", + "nodeSelector": "nodeSelector defines the node selection constraints for the image pruner pod.", + "tolerations": "tolerations defines the node tolerations for the image pruner pod.", + "successfulJobsHistoryLimit": "successfulJobsHistoryLimit specifies how many successful image pruner jobs to retain. Defaults to 3 if not set.", + "failedJobsHistoryLimit": "failedJobsHistoryLimit specifies how many failed image pruner jobs to retain. Defaults to 3 if not set.", + "ignoreInvalidImageReferences": "ignoreInvalidImageReferences indicates whether the pruner can ignore errors while parsing image references.", } func (ImagePrunerSpec) SwaggerDoc() map[string]string { diff --git a/vendor/github.com/openshift/api/install.go b/vendor/github.com/openshift/api/install.go index 11c6512c526a..8422d2015824 100644 --- a/vendor/github.com/openshift/api/install.go +++ b/vendor/github.com/openshift/api/install.go @@ -37,6 +37,7 @@ import ( "github.com/openshift/api/authorization" "github.com/openshift/api/build" "github.com/openshift/api/config" + "github.com/openshift/api/helm" "github.com/openshift/api/image" "github.com/openshift/api/imageregistry" "github.com/openshift/api/kubecontrolplane" @@ -65,6 +66,7 @@ var ( authorization.Install, build.Install, config.Install, + helm.Install, image.Install, imageregistry.Install, kubecontrolplane.Install, diff --git a/vendor/github.com/openshift/api/operator/v1/0000_10_config-operator_01_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_10_config-operator_01_config.crd.yaml index 8ce9fe994e94..6beaeb259d4e 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_10_config-operator_01_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_10_config-operator_01_config.crd.yaml @@ -1,139 +1,146 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: configs.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: scope: Cluster - preserveUnknownFields: false group: operator.openshift.io - version: v1 names: kind: Config plural: configs singular: config categories: - coreoperators - subresources: - status: {} - validation: - openAPIV3Schema: - description: Config provides information to configure the config operator. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec is the specification of the desired behavior of the Config - Operator. - type: object - properties: - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - description: status defines the observed status of the Config Operator. - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: Config provides information to configure the config operator. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the specification of the desired behavior of the + Config Operator. + type: object + properties: + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + description: status defines the observed status of the Config Operator. + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_20_etcd-operator_01.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_20_etcd-operator_01.crd.yaml index ad1eadc5fd79..14f6aeb5761b 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_20_etcd-operator_01.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_20_etcd-operator_01.crd.yaml @@ -1,197 +1,205 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: etcds.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: scope: Cluster group: operator.openshift.io - version: v1 names: kind: Etcd plural: etcds singular: etcd categories: - coreoperators - preserveUnknownFields: false - subresources: - status: {} - "validation": - "openAPIV3Schema": - description: Etcd provides information to configure an operator to manage kube-apiserver. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - type: object - properties: - failedRevisionLimit: - description: failedRevisionLimit is the number of failed static pod - installer revisions to keep on disk and in the api -1 = unlimited, - 0 or unset = 5 (default) - type: integer - format: int32 - forceRedeploymentReason: - description: forceRedeploymentReason can be used to force the redeployment - of the operand by providing a unique string. This provides a mechanism - to kick a previously failed deployment and provide a reason why you - think it will work this time instead of failing again on the same - config. - type: string - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - succeededRevisionLimit: - description: succeededRevisionLimit is the number of successful static - pod installer revisions to keep on disk and in the api -1 = unlimited, - 0 or unset = 5 (default) - type: integer - format: int32 - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: Etcd provides information to configure an operator to manage + kube-apiserver. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + properties: + failedRevisionLimit: + description: failedRevisionLimit is the number of failed static pod + installer revisions to keep on disk and in the api -1 = unlimited, + 0 or unset = 5 (default) + type: integer + format: int32 + forceRedeploymentReason: + description: forceRedeploymentReason can be used to force the redeployment + of the operand by providing a unique string. This provides a mechanism + to kick a previously failed deployment and provide a reason why + you think it will work this time instead of failing again on the + same config. + type: string + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + succeededRevisionLimit: + description: succeededRevisionLimit is the number of successful static + pod installer revisions to keep on disk and in the api -1 = unlimited, + 0 or unset = 5 (default) + type: integer + format: int32 + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - latestAvailableRevision: - description: latestAvailableRevision is the deploymentID of the most - recent deployment - type: integer - format: int32 - latestAvailableRevisionReason: - description: latestAvailableRevisionReason describe the detailed reason - for the most recent deployment - type: string - nodeStatuses: - description: nodeStatuses track the deployment values and errors across - individual nodes - type: array - items: - description: NodeStatus provides information about the current state - of a particular node managed by this operator. - type: object - properties: - currentRevision: - description: currentRevision is the generation of the most recently - successful deployment - type: integer - format: int32 - lastFailedRevision: - description: lastFailedRevision is the generation of the deployment - we tried and failed to deploy. - type: integer - format: int32 - lastFailedRevisionErrors: - description: lastFailedRevisionErrors is a list of the errors - during the failed deployment referenced in lastFailedRevision - type: array - items: + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + latestAvailableRevision: + description: latestAvailableRevision is the deploymentID of the most + recent deployment + type: integer + format: int32 + latestAvailableRevisionReason: + description: latestAvailableRevisionReason describe the detailed reason + for the most recent deployment + type: string + nodeStatuses: + description: nodeStatuses track the deployment values and errors across + individual nodes + type: array + items: + description: NodeStatus provides information about the current state + of a particular node managed by this operator. + type: object + properties: + currentRevision: + description: currentRevision is the generation of the most recently + successful deployment + type: integer + format: int32 + lastFailedRevision: + description: lastFailedRevision is the generation of the deployment + we tried and failed to deploy. + type: integer + format: int32 + lastFailedRevisionErrors: + description: lastFailedRevisionErrors is a list of the errors + during the failed deployment referenced in lastFailedRevision + type: array + items: + type: string + nodeName: + description: nodeName is the name of the node type: string - nodeName: - description: nodeName is the name of the node - type: string - targetRevision: - description: targetRevision is the generation of the deployment - we're trying to apply - type: integer - format: int32 - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + targetRevision: + description: targetRevision is the generation of the deployment + we're trying to apply + type: integer + format: int32 + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml index 83d5a5a39df5..b695ce8381f7 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml @@ -1,6 +1,8 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + include.release.openshift.io/self-managed-high-availability: "true" name: kubeapiservers.operator.openshift.io spec: group: operator.openshift.io @@ -8,193 +10,198 @@ spec: kind: KubeAPIServer plural: kubeapiservers singular: kubeapiserver - preserveUnknownFields: false scope: Cluster - subresources: - status: {} - validation: - openAPIV3Schema: - description: KubeAPIServer provides information to configure an operator to - manage kube-apiserver. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec is the specification of the desired behavior of the Kubernetes - API Server - properties: - failedRevisionLimit: - description: failedRevisionLimit is the number of failed static pod - installer revisions to keep on disk and in the api -1 = unlimited, - 0 or unset = 5 (default) - format: int32 - type: integer - forceRedeploymentReason: - description: forceRedeploymentReason can be used to force the redeployment - of the operand by providing a unique string. This provides a mechanism - to kick a previously failed deployment and provide a reason why you - think it will work this time instead of failing again on the same - config. - type: string - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - pattern: ^(Managed|Force)$ - type: string - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - nullable: true - type: object - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - succeededRevisionLimit: - description: succeededRevisionLimit is the number of successful static - pod installer revisions to keep on disk and in the api -1 = unlimited, - 0 or unset = 5 (default) - format: int32 - type: integer - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - nullable: true - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - status: - description: status is the most recently observed status of the Kubernetes - API Server - properties: - conditions: - description: conditions is a list of conditions and their status - items: - description: OperatorCondition is just the standard condition fields. - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string + versions: + - name: v1 + schema: + openAPIV3Schema: + description: KubeAPIServer provides information to configure an operator to + manage kube-apiserver. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the specification of the desired behavior of the + Kubernetes API Server + properties: + failedRevisionLimit: + description: failedRevisionLimit is the number of failed static pod + installer revisions to keep on disk and in the api -1 = unlimited, + 0 or unset = 5 (default) + format: int32 + type: integer + forceRedeploymentReason: + description: forceRedeploymentReason can be used to force the redeployment + of the operand by providing a unique string. This provides a mechanism + to kick a previously failed deployment and provide a reason why + you think it will work this time instead of failing again on the + same config. + type: string + logLevel: + default: Normal + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + managementState: + description: managementState indicates whether and how the operator + should manage the component + pattern: ^(Managed|Force)$ + type: string + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + nullable: true type: object - type: array - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - format: int64 - type: integer - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + succeededRevisionLimit: + description: succeededRevisionLimit is the number of successful static + pod installer revisions to keep on disk and in the api -1 = unlimited, + 0 or unset = 5 (default) + format: int32 + type: integer + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' + nullable: true type: object - type: array - latestAvailableRevision: - description: latestAvailableRevision is the deploymentID of the most - recent deployment - format: int32 - type: integer - latestAvailableRevisionReason: - description: latestAvailableRevisionReason describe the detailed reason - for the most recent deployment - type: string - nodeStatuses: - description: nodeStatuses track the deployment values and errors across - individual nodes - items: - description: NodeStatus provides information about the current state - of a particular node managed by this operator. - properties: - currentRevision: - description: currentRevision is the generation of the most recently - successful deployment - format: int32 - type: integer - lastFailedRevision: - description: lastFailedRevision is the generation of the deployment - we tried and failed to deploy. - format: int32 - type: integer - lastFailedRevisionErrors: - description: lastFailedRevisionErrors is a list of the errors - during the failed deployment referenced in lastFailedRevision - items: + x-kubernetes-preserve-unknown-fields: true + type: object + status: + description: status is the most recently observed status of the Kubernetes + API Server + properties: + conditions: + description: conditions is a list of conditions and their status + items: + description: OperatorCondition is just the standard condition fields. + properties: + lastTransitionTime: + format: date-time type: string - type: array - nodeName: - description: nodeName is the name of the node - type: string - targetRevision: - description: targetRevision is the generation of the deployment - we're trying to apply - format: int32 - type: integer - type: object - type: array - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - format: int64 - type: integer - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - format: int32 - type: integer - version: - description: version is the level this availability applies to - type: string - type: object - required: - - spec - type: object - version: v1 + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + format: int64 + type: integer + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + type: object + type: array + latestAvailableRevision: + description: latestAvailableRevision is the deploymentID of the most + recent deployment + format: int32 + type: integer + latestAvailableRevisionReason: + description: latestAvailableRevisionReason describe the detailed reason + for the most recent deployment + type: string + nodeStatuses: + description: nodeStatuses track the deployment values and errors across + individual nodes + items: + description: NodeStatus provides information about the current state + of a particular node managed by this operator. + properties: + currentRevision: + description: currentRevision is the generation of the most recently + successful deployment + format: int32 + type: integer + lastFailedRevision: + description: lastFailedRevision is the generation of the deployment + we tried and failed to deploy. + format: int32 + type: integer + lastFailedRevisionErrors: + description: lastFailedRevisionErrors is a list of the errors + during the failed deployment referenced in lastFailedRevision + items: + type: string + type: array + nodeName: + description: nodeName is the name of the node + type: string + targetRevision: + description: targetRevision is the generation of the deployment + we're trying to apply + format: int32 + type: integer + type: object + type: array + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + format: int64 + type: integer + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + format: int32 + type: integer + version: + description: version is the level this availability applies to + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml-merge-patch b/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml-merge-patch deleted file mode 100644 index be6a3cc2e7fb..000000000000 --- a/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml-merge-patch +++ /dev/null @@ -1,8 +0,0 @@ -spec: - validation: - openAPIV3Schema: - properties: - spec: - properties: - managementState: - pattern: "^(Managed|Force)$" \ No newline at end of file diff --git a/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml-patch b/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml-patch new file mode 100644 index 000000000000..8145f00c49bc --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/0000_20_kube-apiserver-operator_01_config.crd.yaml-patch @@ -0,0 +1,3 @@ +- op: replace + path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/managementState/pattern + value: "^(Managed|Force)$" diff --git a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml index 257620128ca7..6f08cec5d93c 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml @@ -1,6 +1,8 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + include.release.openshift.io/self-managed-high-availability: "true" name: kubecontrollermanagers.operator.openshift.io spec: group: operator.openshift.io @@ -10,193 +12,198 @@ spec: kind: KubeControllerManager plural: kubecontrollermanagers singular: kubecontrollermanager - preserveUnknownFields: false scope: Cluster - subresources: - status: {} - validation: - openAPIV3Schema: - description: KubeControllerManager provides information to configure an operator - to manage kube-controller-manager. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec is the specification of the desired behavior of the Kubernetes - Controller Manager - properties: - failedRevisionLimit: - description: failedRevisionLimit is the number of failed static pod - installer revisions to keep on disk and in the api -1 = unlimited, - 0 or unset = 5 (default) - format: int32 - type: integer - forceRedeploymentReason: - description: forceRedeploymentReason can be used to force the redeployment - of the operand by providing a unique string. This provides a mechanism - to kick a previously failed deployment and provide a reason why you - think it will work this time instead of failing again on the same - config. - type: string - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - pattern: ^(Managed|Force)$ - type: string - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - nullable: true - type: object - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - succeededRevisionLimit: - description: succeededRevisionLimit is the number of successful static - pod installer revisions to keep on disk and in the api -1 = unlimited, - 0 or unset = 5 (default) - format: int32 - type: integer - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - nullable: true - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - status: - description: status is the most recently observed status of the Kubernetes - Controller Manager - properties: - conditions: - description: conditions is a list of conditions and their status - items: - description: OperatorCondition is just the standard condition fields. - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string + versions: + - name: v1 + schema: + openAPIV3Schema: + description: KubeControllerManager provides information to configure an operator + to manage kube-controller-manager. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the specification of the desired behavior of the + Kubernetes Controller Manager + properties: + failedRevisionLimit: + description: failedRevisionLimit is the number of failed static pod + installer revisions to keep on disk and in the api -1 = unlimited, + 0 or unset = 5 (default) + format: int32 + type: integer + forceRedeploymentReason: + description: forceRedeploymentReason can be used to force the redeployment + of the operand by providing a unique string. This provides a mechanism + to kick a previously failed deployment and provide a reason why + you think it will work this time instead of failing again on the + same config. + type: string + logLevel: + default: Normal + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + managementState: + description: managementState indicates whether and how the operator + should manage the component + pattern: ^(Managed|Force)$ + type: string + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + nullable: true type: object - type: array - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - format: int64 - type: integer - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + succeededRevisionLimit: + description: succeededRevisionLimit is the number of successful static + pod installer revisions to keep on disk and in the api -1 = unlimited, + 0 or unset = 5 (default) + format: int32 + type: integer + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' + nullable: true type: object - type: array - latestAvailableRevision: - description: latestAvailableRevision is the deploymentID of the most - recent deployment - format: int32 - type: integer - latestAvailableRevisionReason: - description: latestAvailableRevisionReason describe the detailed reason - for the most recent deployment - type: string - nodeStatuses: - description: nodeStatuses track the deployment values and errors across - individual nodes - items: - description: NodeStatus provides information about the current state - of a particular node managed by this operator. - properties: - currentRevision: - description: currentRevision is the generation of the most recently - successful deployment - format: int32 - type: integer - lastFailedRevision: - description: lastFailedRevision is the generation of the deployment - we tried and failed to deploy. - format: int32 - type: integer - lastFailedRevisionErrors: - description: lastFailedRevisionErrors is a list of the errors - during the failed deployment referenced in lastFailedRevision - items: + x-kubernetes-preserve-unknown-fields: true + type: object + status: + description: status is the most recently observed status of the Kubernetes + Controller Manager + properties: + conditions: + description: conditions is a list of conditions and their status + items: + description: OperatorCondition is just the standard condition fields. + properties: + lastTransitionTime: + format: date-time type: string - type: array - nodeName: - description: nodeName is the name of the node - type: string - targetRevision: - description: targetRevision is the generation of the deployment - we're trying to apply - format: int32 - type: integer - type: object - type: array - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - format: int64 - type: integer - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - format: int32 - type: integer - version: - description: version is the level this availability applies to - type: string - type: object - required: - - spec - type: object - version: v1 + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + format: int64 + type: integer + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + type: object + type: array + latestAvailableRevision: + description: latestAvailableRevision is the deploymentID of the most + recent deployment + format: int32 + type: integer + latestAvailableRevisionReason: + description: latestAvailableRevisionReason describe the detailed reason + for the most recent deployment + type: string + nodeStatuses: + description: nodeStatuses track the deployment values and errors across + individual nodes + items: + description: NodeStatus provides information about the current state + of a particular node managed by this operator. + properties: + currentRevision: + description: currentRevision is the generation of the most recently + successful deployment + format: int32 + type: integer + lastFailedRevision: + description: lastFailedRevision is the generation of the deployment + we tried and failed to deploy. + format: int32 + type: integer + lastFailedRevisionErrors: + description: lastFailedRevisionErrors is a list of the errors + during the failed deployment referenced in lastFailedRevision + items: + type: string + type: array + nodeName: + description: nodeName is the name of the node + type: string + targetRevision: + description: targetRevision is the generation of the deployment + we're trying to apply + format: int32 + type: integer + type: object + type: array + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + format: int64 + type: integer + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + format: int32 + type: integer + version: + description: version is the level this availability applies to + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml-merge-patch b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml-merge-patch deleted file mode 100644 index 5cc312a439fd..000000000000 --- a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml-merge-patch +++ /dev/null @@ -1,10 +0,0 @@ -# this file can be removed once we switch to v0.2 of crd generator -# see: https://github.com/openshift/cluster-kube-scheduler-operator/pull/148 -spec: - validation: - openAPIV3Schema: - properties: - spec: - properties: - managementState: - pattern: "^(Managed|Force)$" diff --git a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml-patch b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml-patch new file mode 100644 index 000000000000..8145f00c49bc --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-controller-manager-operator_01_config.crd.yaml-patch @@ -0,0 +1,3 @@ +- op: replace + path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/managementState/pattern + value: "^(Managed|Force)$" diff --git a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml index 7d7ac277d500..faf3f04486b0 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml @@ -1,6 +1,8 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + include.release.openshift.io/self-managed-high-availability: "true" name: kubeschedulers.operator.openshift.io spec: group: operator.openshift.io @@ -10,193 +12,198 @@ spec: kind: KubeScheduler plural: kubeschedulers singular: kubescheduler - preserveUnknownFields: false scope: Cluster - subresources: - status: {} - validation: - openAPIV3Schema: - description: KubeScheduler provides information to configure an operator to - manage scheduler. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec is the specification of the desired behavior of the Kubernetes - Scheduler - properties: - failedRevisionLimit: - description: failedRevisionLimit is the number of failed static pod - installer revisions to keep on disk and in the api -1 = unlimited, - 0 or unset = 5 (default) - format: int32 - type: integer - forceRedeploymentReason: - description: forceRedeploymentReason can be used to force the redeployment - of the operand by providing a unique string. This provides a mechanism - to kick a previously failed deployment and provide a reason why you - think it will work this time instead of failing again on the same - config. - type: string - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - pattern: ^(Managed|Force)$ - type: string - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - nullable: true - type: object - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - succeededRevisionLimit: - description: succeededRevisionLimit is the number of successful static - pod installer revisions to keep on disk and in the api -1 = unlimited, - 0 or unset = 5 (default) - format: int32 - type: integer - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - nullable: true - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - status: - description: status is the most recently observed status of the Kubernetes - Scheduler - properties: - conditions: - description: conditions is a list of conditions and their status - items: - description: OperatorCondition is just the standard condition fields. - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string + versions: + - name: v1 + schema: + openAPIV3Schema: + description: KubeScheduler provides information to configure an operator to + manage scheduler. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the specification of the desired behavior of the + Kubernetes Scheduler + properties: + failedRevisionLimit: + description: failedRevisionLimit is the number of failed static pod + installer revisions to keep on disk and in the api -1 = unlimited, + 0 or unset = 5 (default) + format: int32 + type: integer + forceRedeploymentReason: + description: forceRedeploymentReason can be used to force the redeployment + of the operand by providing a unique string. This provides a mechanism + to kick a previously failed deployment and provide a reason why + you think it will work this time instead of failing again on the + same config. + type: string + logLevel: + default: Normal + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + managementState: + description: managementState indicates whether and how the operator + should manage the component + pattern: ^(Managed|Force)$ + type: string + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + nullable: true type: object - type: array - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - format: int64 - type: integer - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + succeededRevisionLimit: + description: succeededRevisionLimit is the number of successful static + pod installer revisions to keep on disk and in the api -1 = unlimited, + 0 or unset = 5 (default) + format: int32 + type: integer + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' + nullable: true type: object - type: array - latestAvailableRevision: - description: latestAvailableRevision is the deploymentID of the most - recent deployment - format: int32 - type: integer - latestAvailableRevisionReason: - description: latestAvailableRevisionReason describe the detailed reason - for the most recent deployment - type: string - nodeStatuses: - description: nodeStatuses track the deployment values and errors across - individual nodes - items: - description: NodeStatus provides information about the current state - of a particular node managed by this operator. - properties: - currentRevision: - description: currentRevision is the generation of the most recently - successful deployment - format: int32 - type: integer - lastFailedRevision: - description: lastFailedRevision is the generation of the deployment - we tried and failed to deploy. - format: int32 - type: integer - lastFailedRevisionErrors: - description: lastFailedRevisionErrors is a list of the errors - during the failed deployment referenced in lastFailedRevision - items: + x-kubernetes-preserve-unknown-fields: true + type: object + status: + description: status is the most recently observed status of the Kubernetes + Scheduler + properties: + conditions: + description: conditions is a list of conditions and their status + items: + description: OperatorCondition is just the standard condition fields. + properties: + lastTransitionTime: + format: date-time type: string - type: array - nodeName: - description: nodeName is the name of the node - type: string - targetRevision: - description: targetRevision is the generation of the deployment - we're trying to apply - format: int32 - type: integer - type: object - type: array - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - format: int64 - type: integer - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - format: int32 - type: integer - version: - description: version is the level this availability applies to - type: string - type: object - required: - - spec - type: object - version: v1 + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + format: int64 + type: integer + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + type: object + type: array + latestAvailableRevision: + description: latestAvailableRevision is the deploymentID of the most + recent deployment + format: int32 + type: integer + latestAvailableRevisionReason: + description: latestAvailableRevisionReason describe the detailed reason + for the most recent deployment + type: string + nodeStatuses: + description: nodeStatuses track the deployment values and errors across + individual nodes + items: + description: NodeStatus provides information about the current state + of a particular node managed by this operator. + properties: + currentRevision: + description: currentRevision is the generation of the most recently + successful deployment + format: int32 + type: integer + lastFailedRevision: + description: lastFailedRevision is the generation of the deployment + we tried and failed to deploy. + format: int32 + type: integer + lastFailedRevisionErrors: + description: lastFailedRevisionErrors is a list of the errors + during the failed deployment referenced in lastFailedRevision + items: + type: string + type: array + nodeName: + description: nodeName is the name of the node + type: string + targetRevision: + description: targetRevision is the generation of the deployment + we're trying to apply + format: int32 + type: integer + type: object + type: array + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + format: int64 + type: integer + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + format: int32 + type: integer + version: + description: version is the level this availability applies to + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml-merge-patch b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml-merge-patch deleted file mode 100644 index 5cc312a439fd..000000000000 --- a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml-merge-patch +++ /dev/null @@ -1,10 +0,0 @@ -# this file can be removed once we switch to v0.2 of crd generator -# see: https://github.com/openshift/cluster-kube-scheduler-operator/pull/148 -spec: - validation: - openAPIV3Schema: - properties: - spec: - properties: - managementState: - pattern: "^(Managed|Force)$" diff --git a/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml-patch b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml-patch new file mode 100644 index 000000000000..8145f00c49bc --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/0000_25_kube-scheduler-operator_01_config.crd.yaml-patch @@ -0,0 +1,3 @@ +- op: replace + path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/managementState/pattern + value: "^(Managed|Force)$" diff --git a/vendor/github.com/openshift/api/operator/v1/0000_30_openshift-apiserver-operator_01_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_30_openshift-apiserver-operator_01_config.crd.yaml index 2fdc2ddb3655..b6bba3cc6ebd 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_30_openshift-apiserver-operator_01_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_30_openshift-apiserver-operator_01_config.crd.yaml @@ -1,147 +1,154 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: openshiftapiservers.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: scope: Cluster - preserveUnknownFields: false group: operator.openshift.io - version: v1 names: kind: OpenShiftAPIServer plural: openshiftapiservers singular: openshiftapiserver categories: - coreoperators - subresources: - status: {} - validation: - openAPIV3Schema: - description: OpenShiftAPIServer provides information to configure an operator - to manage openshift-apiserver. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec is the specification of the desired behavior of the OpenShift - API Server. - type: object - properties: - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - description: status defines the observed status of the OpenShift API Server. - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: OpenShiftAPIServer provides information to configure an operator + to manage openshift-apiserver. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the specification of the desired behavior of the + OpenShift API Server. + type: object + properties: + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - latestAvailableRevision: - description: latestAvailableRevision is the latest revision used as - suffix of revisioned secrets like encryption-config. A new revision - causes a new deployment of pods. - type: integer - format: int32 - minimum: 0 - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + description: status defines the observed status of the OpenShift API Server. + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + latestAvailableRevision: + description: latestAvailableRevision is the latest revision used as + suffix of revisioned secrets like encryption-config. A new revision + causes a new deployment of pods. + type: integer + format: int32 + minimum: 0 + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_40_cloud-credential-operator_00_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_40_cloud-credential-operator_00_config.crd.yaml new file mode 100644 index 000000000000..098de4470ec4 --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/0000_40_cloud-credential-operator_00_config.crd.yaml @@ -0,0 +1,158 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: cloudcredentials.operator.openshift.io +spec: + scope: Cluster + group: operator.openshift.io + names: + kind: CloudCredential + listKind: CloudCredentialList + plural: cloudcredentials + singular: cloudcredential + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: CloudCredential provides a means to configure an operator to + manage CredentialsRequests. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CloudCredentialSpec is the specification of the desired behavior + of the cloud-credential-operator. + type: object + properties: + credentialsMode: + description: CredentialsMode allows informing CCO that it should not + attempt to dynamically determine the root cloud credentials capabilities, + and it should just run in the specified mode. It also allows putting + the operator into "manual" mode if desired. Leaving the field in + default mode runs CCO so that the cluster's cloud credentials will + be dynamically probed for capabilities (on supported clouds/platforms). + type: string + enum: + - "" + - Manual + - Mint + - Passthrough + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + type: object + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' + type: object + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + description: CloudCredentialStatus defines the observed status of the + cloud-credential-operator. + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_40_kube-storage-version-migrator-operator_00_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_40_kube-storage-version-migrator-operator_00_config.crd.yaml index 20ce796cf3b5..9adbb29e602d 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_40_kube-storage-version-migrator-operator_00_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_40_kube-storage-version-migrator-operator_00_config.crd.yaml @@ -1,8 +1,9 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - creationTimestamp: null name: kubestorageversionmigrators.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: operator.openshift.io names: @@ -11,137 +12,132 @@ spec: plural: kubestorageversionmigrators singular: kubestorageversionmigrator scope: Cluster - preserveUnknownFields: false - subresources: - status: {} - version: v1 versions: - name: v1 served: true storage: true - "validation": - "openAPIV3Schema": - description: KubeStorageVersionMigrator provides information to configure an - operator to manage kube-storage-version-migrator. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - type: object - properties: - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + subresources: + status: {} + schema: + "openAPIV3Schema": + description: KubeStorageVersionMigrator provides information to configure + an operator to manage kube-storage-version-migrator. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + properties: + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_50_cluster-authentication-operator_01_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_50_cluster-authentication-operator_01_config.crd.yaml index 87f910ff3932..20cac90b4a82 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_50_cluster-authentication-operator_01_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_50_cluster-authentication-operator_01_config.crd.yaml @@ -1,153 +1,160 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: authentications.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: scope: Cluster - preserveUnknownFields: false group: operator.openshift.io - version: v1 names: kind: Authentication plural: authentications singular: authentication - subresources: - status: {} - validation: - openAPIV3Schema: - description: Authentication provides information to configure an operator to - manage authentication. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - type: object - properties: - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: Authentication provides information to configure an operator + to manage authentication. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + properties: + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' + type: object + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + managingOAuthAPIServer: + description: ManagingOAuthAPIServer indicates whether this operator + is managing OAuth related APIs. Setting this field to true will + cause OAS-O to step down. Note that this field will be removed in + the future releases, once https://github.com/openshift/enhancements/blob/master/enhancements/authentication/separate-oauth-resources.md + is fully implemented + type: boolean + oauthAPIServer: + description: OAuthAPIServer holds status specific only to oauth-apiserver type: object properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved + latestAvailableRevision: + description: LatestAvailableRevision is the latest revision used + as suffix of revisioned secrets like encryption-config. A new + revision causes a new deployment of pods. type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - managingOAuthAPIServer: - description: ManagingOAuthAPIServer indicates whether this operator - is managing OAuth related APIs. Setting this field to true will cause - OAS-O to step down. Note that this field will be removed in the future - releases, once https://github.com/openshift/enhancements/blob/master/enhancements/authentication/separate-oauth-resources.md - is fully implemented - type: boolean - oauthAPIServer: - description: OAuthAPIServer holds status specific only to oauth-apiserver - type: object - properties: - latestAvailableRevision: - description: LatestAvailableRevision is the latest revision used - as suffix of revisioned secrets like encryption-config. A new - revision causes a new deployment of pods. - type: integer - format: int32 - minimum: 0 - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + format: int32 + minimum: 0 + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_50_cluster-openshift-controller-manager-operator_02_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_50_cluster-openshift-controller-manager-operator_02_config.crd.yaml index 589797bb7146..0d9403cd3a75 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_50_cluster-openshift-controller-manager-operator_02_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_50_cluster-openshift-controller-manager-operator_02_config.crd.yaml @@ -1,137 +1,144 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: openshiftcontrollermanagers.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: scope: Cluster - preserveUnknownFields: false group: operator.openshift.io - version: v1 names: kind: OpenShiftControllerManager plural: openshiftcontrollermanagers singular: openshiftcontrollermanager categories: - coreoperators - subresources: - status: {} - validation: - openAPIV3Schema: - description: OpenShiftControllerManager provides information to configure an - operator to manage openshift-controller-manager. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - type: object - properties: - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: OpenShiftControllerManager provides information to configure + an operator to manage openshift-controller-manager. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + properties: + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_50_cluster_storage_operator_01_crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_50_cluster_storage_operator_01_crd.yaml index 28d7c88373fe..a05f40888724 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_50_cluster_storage_operator_01_crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_50_cluster_storage_operator_01_crd.yaml @@ -1,142 +1,145 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: storages.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: operator.openshift.io names: kind: Storage plural: storages singular: storage - preserveUnknownFields: false scope: Cluster - subresources: - status: {} - version: v1 versions: - name: v1 served: true storage: true - validation: - openAPIV3Schema: - description: Storage provides a means to configure an operator to manage the - cluster storage operator. `cluster` is the canonical name. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec holds user settable values for configuration - type: object - properties: - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - description: status holds observed values from the cluster. They may not - be overridden. - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + subresources: + status: {} + schema: + openAPIV3Schema: + description: Storage provides a means to configure an operator to manage the + cluster storage operator. `cluster` is the canonical name. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + type: object + properties: + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + description: status holds observed values from the cluster. They may not + be overridden. + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml index 2ee6184f60f3..7c14492ab630 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml @@ -1,7 +1,8 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - creationTimestamp: null + annotations: + include.release.openshift.io/self-managed-high-availability: "true" name: ingresscontrollers.operator.openshift.io spec: group: operator.openshift.io @@ -10,861 +11,1024 @@ spec: listKind: IngressControllerList plural: ingresscontrollers singular: ingresscontroller - preserveUnknownFields: false - scope: "" - subresources: - scale: - labelSelectorPath: .status.selector - specReplicasPath: .spec.replicas - statusReplicasPath: .status.availableReplicas - status: {} - validation: - openAPIV3Schema: - description: "IngressController describes a managed ingress controller for the - cluster. The controller can service OpenShift Route and Kubernetes Ingress - resources. \n When an IngressController is created, a new ingress controller - deployment is created to allow external traffic to reach the services that - expose Ingress or Route resources. Updating this resource may lead to disruption - for public facing network connections as a new ingress controller revision - may be rolled out. \n https://kubernetes.io/docs/concepts/services-networking/ingress-controllers - \n Whenever possible, sensible defaults for the platform are used. See each - field for more details." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec is the specification of the desired behavior of the IngressController. - properties: - defaultCertificate: - description: "defaultCertificate is a reference to a secret containing - the default certificate served by the ingress controller. When Routes - don't specify their own certificate, defaultCertificate is used. \n - The secret must contain the following keys and data: \n tls.crt: - certificate file contents tls.key: key file contents \n If unset, - a wildcard certificate is automatically generated and used. The certificate - is valid for the ingress controller domain (and subdomains) and the - generated certificate's CA will be automatically integrated with the - cluster's trust store. \n The in-use certificate (whether generated - or user-specified) will be automatically integrated with OpenShift's - built-in OAuth server." - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - domain: - description: "domain is a DNS name serviced by the ingress controller - and is used to configure multiple features: \n * For the LoadBalancerService - endpoint publishing strategy, domain is used to configure DNS records. - See endpointPublishingStrategy. \n * When using a generated default - certificate, the certificate will be valid for domain and its subdomains. - See defaultCertificate. \n * The value is published to individual - Route statuses so that end-users know where to target external DNS - records. \n domain must be unique among all IngressControllers, and - cannot be updated. \n If empty, defaults to ingress.config.openshift.io/cluster - .spec.domain." - type: string - endpointPublishingStrategy: - description: "endpointPublishingStrategy is used to publish the ingress - controller endpoints to other networks, enable load balancer integrations, - etc. \n If unset, the default is based on infrastructure.config.openshift.io/cluster - .status.platform: \n AWS: LoadBalancerService (with External - scope) Azure: LoadBalancerService (with External scope) GCP: - \ LoadBalancerService (with External scope) IBMCloud: LoadBalancerService - (with External scope) Libvirt: HostNetwork \n Any other platform - types (including None) default to HostNetwork. \n endpointPublishingStrategy - cannot be updated." - properties: - hostNetwork: - description: hostNetwork holds parameters for the HostNetwork endpoint - publishing strategy. Present only if type is HostNetwork. - type: object - loadBalancer: - description: loadBalancer holds parameters for the load balancer. - Present only if type is LoadBalancerService. - properties: - providerParameters: - description: "providerParameters holds desired load balancer - information specific to the underlying infrastructure provider. - \n If empty, defaults will be applied. See specific providerParameters - fields for details about their defaults." - properties: - aws: - description: "aws provides configuration settings that are - specific to AWS load balancers. \n If empty, defaults - will be applied. See specific aws fields for details about - their defaults." + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: "IngressController describes a managed ingress controller for + the cluster. The controller can service OpenShift Route and Kubernetes Ingress + resources. \n When an IngressController is created, a new ingress controller + deployment is created to allow external traffic to reach the services that + expose Ingress or Route resources. Updating this resource may lead to disruption + for public facing network connections as a new ingress controller revision + may be rolled out. \n https://kubernetes.io/docs/concepts/services-networking/ingress-controllers + \n Whenever possible, sensible defaults for the platform are used. See each + field for more details." + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the specification of the desired behavior of the + IngressController. + properties: + defaultCertificate: + description: "defaultCertificate is a reference to a secret containing + the default certificate served by the ingress controller. When Routes + don't specify their own certificate, defaultCertificate is used. + \n The secret must contain the following keys and data: \n tls.crt: + certificate file contents tls.key: key file contents \n If unset, + a wildcard certificate is automatically generated and used. The + certificate is valid for the ingress controller domain (and subdomains) + and the generated certificate's CA will be automatically integrated + with the cluster's trust store. \n If a wildcard certificate is + used and shared by multiple HTTP/2 enabled routes (which implies + ALPN) then clients (i.e., notably browsers) are at liberty to reuse + open connections. This means a client can reuse a connection to + another route and that is likely to fail. This behaviour is generally + known as connection coalescing. \n The in-use certificate (whether + generated or user-specified) will be automatically integrated with + OpenShift's built-in OAuth server." + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + domain: + description: "domain is a DNS name serviced by the ingress controller + and is used to configure multiple features: \n * For the LoadBalancerService + endpoint publishing strategy, domain is used to configure DNS + records. See endpointPublishingStrategy. \n * When using a generated + default certificate, the certificate will be valid for domain + and its subdomains. See defaultCertificate. \n * The value is published + to individual Route statuses so that end-users know where to target + external DNS records. \n domain must be unique among all IngressControllers, + and cannot be updated. \n If empty, defaults to ingress.config.openshift.io/cluster + .spec.domain." + type: string + endpointPublishingStrategy: + description: "endpointPublishingStrategy is used to publish the ingress + controller endpoints to other networks, enable load balancer integrations, + etc. \n If unset, the default is based on infrastructure.config.openshift.io/cluster + .status.platform: \n AWS: LoadBalancerService (with External + scope) Azure: LoadBalancerService (with External scope) GCP: + \ LoadBalancerService (with External scope) IBMCloud: LoadBalancerService + (with External scope) Libvirt: HostNetwork \n Any other platform + types (including None) default to HostNetwork. \n endpointPublishingStrategy + cannot be updated." + properties: + hostNetwork: + description: hostNetwork holds parameters for the HostNetwork + endpoint publishing strategy. Present only if type is HostNetwork. + type: object + loadBalancer: + description: loadBalancer holds parameters for the load balancer. + Present only if type is LoadBalancerService. + properties: + providerParameters: + description: "providerParameters holds desired load balancer + information specific to the underlying infrastructure provider. + \n If empty, defaults will be applied. See specific providerParameters + fields for details about their defaults." + properties: + aws: + description: "aws provides configuration settings that + are specific to AWS load balancers. \n If empty, defaults + will be applied. See specific aws fields for details + about their defaults." + properties: + classicLoadBalancer: + description: classicLoadBalancerParameters holds configuration + parameters for an AWS classic load balancer. Present + only if type is Classic. + type: object + networkLoadBalancer: + description: networkLoadBalancerParameters holds configuration + parameters for an AWS network load balancer. Present + only if type is NLB. + type: object + type: + description: "type is the type of AWS load balancer + to instantiate for an ingresscontroller. \n Valid + values are: \n * \"Classic\": A Classic Load Balancer + that makes routing decisions at either the transport + layer (TCP/SSL) or the application layer (HTTP/HTTPS). + See the following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + \n * \"NLB\": A Network Load Balancer that makes + routing decisions at the transport layer (TCP/SSL). + See the following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb" + enum: + - Classic + - NLB + type: string + required: + - type + type: object + type: + description: type is the underlying infrastructure provider + for the load balancer. Allowed values are "AWS", "Azure", + "BareMetal", "GCP", "OpenStack", and "VSphere". + enum: + - AWS + - Azure + - BareMetal + - GCP + - OpenStack + - VSphere + - IBM + type: string + required: + - type + type: object + scope: + description: scope indicates the scope at which the load balancer + is exposed. Possible values are "External" and "Internal". + enum: + - Internal + - External + type: string + required: + - scope + type: object + nodePort: + description: nodePort holds parameters for the NodePortService + endpoint publishing strategy. Present only if type is NodePortService. + type: object + private: + description: private holds parameters for the Private endpoint + publishing strategy. Present only if type is Private. + type: object + type: + description: "type is the publishing strategy to use. Valid values + are: \n * LoadBalancerService \n Publishes the ingress controller + using a Kubernetes LoadBalancer Service. \n In this configuration, + the ingress controller deployment uses container networking. + A LoadBalancer Service is created to publish the deployment. + \n See: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer + \n If domain is set, a wildcard DNS record will be managed to + point at the LoadBalancer Service's external name. DNS records + are managed only in DNS zones defined by dns.config.openshift.io/cluster + .spec.publicZone and .spec.privateZone. \n Wildcard DNS management + is currently supported only on the AWS, Azure, and GCP platforms. + \n * HostNetwork \n Publishes the ingress controller on node + ports where the ingress controller is deployed. \n In this configuration, + the ingress controller deployment uses host networking, bound + to node ports 80 and 443. The user is responsible for configuring + an external load balancer to publish the ingress controller + via the node ports. \n * Private \n Does not publish the ingress + controller. \n In this configuration, the ingress controller + deployment uses container networking, and is not explicitly + published. The user must manually publish the ingress controller. + \n * NodePortService \n Publishes the ingress controller using + a Kubernetes NodePort Service. \n In this configuration, the + ingress controller deployment uses container networking. A NodePort + Service is created to publish the deployment. The specific node + ports are dynamically allocated by OpenShift; however, to support + static port allocations, user changes to the node port field + of the managed NodePort Service will preserved." + enum: + - LoadBalancerService + - HostNetwork + - Private + - NodePortService + type: string + required: + - type + type: object + httpHeaders: + description: "httpHeaders defines policy for HTTP headers. \n If this + field is empty, the default values are used." + properties: + forwardedHeaderPolicy: + description: "forwardedHeaderPolicy specifies when and how the + IngressController sets the Forwarded, X-Forwarded-For, X-Forwarded-Host, + X-Forwarded-Port, X-Forwarded-Proto, and X-Forwarded-Proto-Version + HTTP headers. The value may be one of the following: \n * \"Append\", + which specifies that the IngressController appends the headers, + preserving existing headers. \n * \"Replace\", which specifies + that the IngressController sets the headers, replacing any + existing Forwarded or X-Forwarded-* headers. \n * \"IfNone\", + which specifies that the IngressController sets the headers + if they are not already set. \n * \"Never\", which specifies + that the IngressController never sets the headers, preserving + any existing headers. \n By default, the policy is \"Append\"." + enum: + - Append + - Replace + - IfNone + - Never + type: string + uniqueId: + description: "uniqueId describes configuration for a custom HTTP + header that the ingress controller should inject into incoming + HTTP requests. Typically, this header is configured to have + a value that is unique to the HTTP request. The header can + be used by applications or included in access logs to facilitate + tracing individual HTTP requests. \n If this field is empty, + no such header is injected into requests." + properties: + format: + description: 'format specifies the format for the injected + HTTP header''s value. This field has no effect unless name + is specified. For the HAProxy-based ingress controller + implementation, this format uses the same syntax as the + HTTP log format. If the field is empty, the default value + is "%{+X}o\\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid"; see the corresponding + HAProxy documentation: http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3' + maxLength: 1024 + minLength: 0 + pattern: ^(%(%|(\{[-+]?[QXE](,[-+]?[QXE])*\})?([A-Za-z]+|\[[.0-9A-Z_a-z]+(\([^)]+\))?(,[.0-9A-Z_a-z]+(\([^)]+\))?)*\]))|[^%[:cntrl:]])*$ + type: string + name: + description: name specifies the name of the HTTP header (for + example, "unique-id") that the ingress controller should + inject into HTTP requests. The field's value must be a + valid HTTP header name as defined in RFC 2616 section 4.2. If + the field is empty, no header is injected. + maxLength: 1024 + minLength: 0 + pattern: ^$|^[-!#$%&'*+.0-9A-Z^_`a-z|~]+$ + type: string + type: object + type: object + logging: + description: logging defines parameters for what should be logged + where. If this field is empty, operational logs are enabled but + access logs are disabled. + properties: + access: + description: "access describes how the client requests should + be logged. \n If this field is empty, access logging is disabled." + properties: + destination: + description: destination is where access logs go. + properties: + container: + description: container holds parameters for the Container + logging destination. Present only if type is Container. + type: object + syslog: + description: syslog holds parameters for a syslog endpoint. Present + only if type is Syslog. + oneOf: + - properties: + address: + format: ipv4 + - properties: + address: + format: ipv6 + properties: + address: + description: address is the IP address of the syslog + endpoint that receives log messages. + type: string + facility: + description: "facility specifies the syslog facility + of log messages. \n If this field is empty, the + facility is \"local1\"." + enum: + - kern + - user + - mail + - daemon + - auth + - syslog + - lpr + - news + - uucp + - cron + - auth2 + - ftp + - ntp + - audit + - alert + - cron2 + - local0 + - local1 + - local2 + - local3 + - local4 + - local5 + - local6 + - local7 + type: string + port: + description: port is the UDP port number of the syslog + endpoint that receives log messages. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - address + - port + type: object + type: + description: "type is the type of destination for logs. + \ It must be one of the following: \n * Container \n + The ingress operator configures the sidecar container + named \"logs\" on the ingress controller pod and configures + the ingress controller to write logs to the sidecar. + \ The logs are then available as container logs. The + expectation is that the administrator configures a custom + logging solution that reads logs from this sidecar. + \ Note that using container logs means that logs may + be dropped if the rate of logs exceeds the container + runtime's or the custom logging solution's capacity. + \n * Syslog \n Logs are sent to a syslog endpoint. The + administrator must specify an endpoint that can receive + syslog messages. The expectation is that the administrator + has configured a custom syslog instance." + enum: + - Container + - Syslog + type: string + required: + - type + type: object + httpCaptureCookies: + description: httpCaptureCookies specifies HTTP cookies that + should be captured in access logs. If this field is empty, + no cookies are captured. + items: + description: IngressControllerCaptureHTTPCookie describes + an HTTP cookie that should be captured. properties: - classicLoadBalancer: - description: classicLoadBalancerParameters holds configuration - parameters for an AWS classic load balancer. Present - only if type is Classic. - type: object - networkLoadBalancer: - description: networkLoadBalancerParameters holds configuration - parameters for an AWS network load balancer. Present - only if type is NLB. - type: object - type: - description: "type is the type of AWS load balancer - to instantiate for an ingresscontroller. \n Valid - values are: \n * \"Classic\": A Classic Load Balancer - that makes routing decisions at either the transport - layer (TCP/SSL) or the application layer (HTTP/HTTPS). - See the following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb - \n * \"NLB\": A Network Load Balancer that makes routing - decisions at the transport layer (TCP/SSL). See - the following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb" + matchType: + description: matchType specifies the type of match to + be performed on the cookie name. Allowed values are + "Exact" for an exact string match and "Prefix" for + a string prefix match. If "Exact" is specified, a + name must be specified in the name field. If "Prefix" + is provided, a prefix must be specified in the namePrefix + field. For example, specifying matchType "Prefix" + and namePrefix "foo" will capture a cookie named "foo" + or "foobar" but not one named "bar". The first matching + cookie is captured. enum: - - Classic - - NLB + - Exact + - Prefix + type: string + maxLength: + description: maxLength specifies a maximum length of + the string that will be logged, which includes the + cookie name, cookie value, and one-character delimiter. If + the log entry exceeds this length, the value will + be truncated in the log message. Note that the ingress + controller may impose a separate bound on the total + length of HTTP headers in a request. + maximum: 1024 + minimum: 1 + type: integer + name: + description: name specifies a cookie name. Its value + must be a valid HTTP cookie name as defined in RFC + 6265 section 4.1. + maxLength: 1024 + minLength: 0 + pattern: ^[-!#$%&'*+.0-9A-Z^_`a-z|~]*$ + type: string + namePrefix: + description: namePrefix specifies a cookie name prefix. Its + value must be a valid HTTP cookie name as defined + in RFC 6265 section 4.1. + maxLength: 1024 + minLength: 0 + pattern: ^[-!#$%&'*+.0-9A-Z^_`a-z|~]*$ type: string required: - - type + - matchType + - maxLength type: object - type: - description: type is the underlying infrastructure provider - for the load balancer. Allowed values are "AWS", "Azure", - "BareMetal", "GCP", "OpenStack", and "VSphere". - enum: - - AWS - - Azure - - BareMetal - - GCP - - OpenStack - - VSphere + maxItems: 1 + nullable: true + type: array + httpCaptureHeaders: + description: "httpCaptureHeaders defines HTTP headers that + should be captured in access logs. If this field is empty, + no headers are captured. \n Note that this option only applies + to cleartext HTTP connections and to secure HTTP connections + for which the ingress controller terminates encryption (that + is, edge-terminated or reencrypt connections). Headers + cannot be captured for TLS passthrough connections." + properties: + request: + description: "request specifies which HTTP request headers + to capture. \n If this field is empty, no request headers + are captured." + items: + description: IngressControllerCaptureHTTPHeader describes + an HTTP header that should be captured. + properties: + maxLength: + description: maxLength specifies a maximum length + for the header value. If a header value exceeds + this length, the value will be truncated in the + log message. Note that the ingress controller + may impose a separate bound on the total length + of HTTP headers in a request. + minimum: 1 + type: integer + name: + description: name specifies a header name. Its + value must be a valid HTTP header name as defined + in RFC 2616 section 4.2. + pattern: ^[-!#$%&'*+.0-9A-Z^_`a-z|~]+$ + type: string + required: + - maxLength + - name + type: object + nullable: true + type: array + response: + description: "response specifies which HTTP response headers + to capture. \n If this field is empty, no response headers + are captured." + items: + description: IngressControllerCaptureHTTPHeader describes + an HTTP header that should be captured. + properties: + maxLength: + description: maxLength specifies a maximum length + for the header value. If a header value exceeds + this length, the value will be truncated in the + log message. Note that the ingress controller + may impose a separate bound on the total length + of HTTP headers in a request. + minimum: 1 + type: integer + name: + description: name specifies a header name. Its + value must be a valid HTTP header name as defined + in RFC 2616 section 4.2. + pattern: ^[-!#$%&'*+.0-9A-Z^_`a-z|~]+$ + type: string + required: + - maxLength + - name + type: object + nullable: true + type: array + type: object + httpLogFormat: + description: "httpLogFormat specifies the format of the log + message for an HTTP request. \n If this field is empty, + log messages use the implementation's default HTTP log format. + \ For HAProxy's default HTTP log format, see the HAProxy + documentation: http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3 + \n Note that this format only applies to cleartext HTTP + connections and to secure HTTP connections for which the + ingress controller terminates encryption (that is, edge-terminated + or reencrypt connections). It does not affect the log format + for TLS passthrough connections." + type: string + required: + - destination + type: object + type: object + namespaceSelector: + description: "namespaceSelector is used to filter the set of namespaces + serviced by the ingress controller. This is useful for implementing + shards. \n If unset, the default is no filtering." + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array required: - - type + - key + - operator type: object - scope: - description: scope indicates the scope at which the load balancer - is exposed. Possible values are "External" and "Internal". - enum: - - Internal - - External + type: array + matchLabels: + additionalProperties: type: string - required: - - scope - type: object - nodePort: - description: nodePort holds parameters for the NodePortService endpoint - publishing strategy. Present only if type is NodePortService. - type: object - private: - description: private holds parameters for the Private endpoint publishing - strategy. Present only if type is Private. - type: object - type: - description: "type is the publishing strategy to use. Valid values - are: \n * LoadBalancerService \n Publishes the ingress controller - using a Kubernetes LoadBalancer Service. \n In this configuration, - the ingress controller deployment uses container networking. A - LoadBalancer Service is created to publish the deployment. \n - See: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer - \n If domain is set, a wildcard DNS record will be managed to - point at the LoadBalancer Service's external name. DNS records - are managed only in DNS zones defined by dns.config.openshift.io/cluster - .spec.publicZone and .spec.privateZone. \n Wildcard DNS management - is currently supported only on the AWS, Azure, and GCP platforms. - \n * HostNetwork \n Publishes the ingress controller on node ports - where the ingress controller is deployed. \n In this configuration, - the ingress controller deployment uses host networking, bound - to node ports 80 and 443. The user is responsible for configuring - an external load balancer to publish the ingress controller via - the node ports. \n * Private \n Does not publish the ingress controller. - \n In this configuration, the ingress controller deployment uses - container networking, and is not explicitly published. The user - must manually publish the ingress controller. \n * NodePortService - \n Publishes the ingress controller using a Kubernetes NodePort - Service. \n In this configuration, the ingress controller deployment - uses container networking. A NodePort Service is created to publish - the deployment. The specific node ports are dynamically allocated - by OpenShift; however, to support static port allocations, user - changes to the node port field of the managed NodePort Service - will preserved." - enum: - - LoadBalancerService - - HostNetwork - - Private - - NodePortService - type: string - required: - - type - type: object - httpHeaders: - description: "httpHeaders defines policy for HTTP headers. \n If this - field is empty, the default values are used." - properties: - forwardedHeaderPolicy: - description: "forwardedHeaderPolicy specifies when and how the IngressController - sets the Forwarded, X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Port, - X-Forwarded-Proto, and X-Forwarded-Proto-Version HTTP headers. - \ The value may be one of the following: \n * \"Append\", which - specifies that the IngressController appends the headers, preserving - existing headers. \n * \"Replace\", which specifies that the IngressController - sets the headers, replacing any existing Forwarded or X-Forwarded-* - headers. \n * \"IfNone\", which specifies that the IngressController - sets the headers if they are not already set. \n * \"Never\", - which specifies that the IngressController never sets the headers, - preserving any existing headers. \n By default, the policy is - \"Append\"." - enum: - - Append - - Replace - - IfNone - - Never - type: string - type: object - logging: - description: logging defines parameters for what should be logged where. If - this field is empty, operational logs are enabled but access logs - are disabled. - properties: - access: - description: "access describes how the client requests should be - logged. \n If this field is empty, access logging is disabled." - properties: - destination: - description: destination is where access logs go. - properties: - container: - description: container holds parameters for the Container - logging destination. Present only if type is Container. - type: object - syslog: - description: syslog holds parameters for a syslog endpoint. Present - only if type is Syslog. - oneOf: - - properties: - address: - format: ipv4 - - properties: - address: - format: ipv6 + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + nodePlacement: + description: "nodePlacement enables explicit control over the scheduling + of the ingress controller. \n If unset, defaults are used. See NodePlacement + for more details." + properties: + nodeSelector: + description: "nodeSelector is the node selector applied to ingress + controller deployments. \n If unset, the default is: \n beta.kubernetes.io/os: + linux node-role.kubernetes.io/worker: '' \n If set, the specified + selector is used and replaces the default." + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. properties: - address: - description: address is the IP address of the syslog - endpoint that receives log messages. + key: + description: key is the label key that the selector + applies to. type: string - facility: - description: "facility specifies the syslog facility - of log messages. \n If this field is empty, the facility - is \"local1\"." - enum: - - kern - - user - - mail - - daemon - - auth - - syslog - - lpr - - news - - uucp - - cron - - auth2 - - ftp - - ntp - - audit - - alert - - cron2 - - local0 - - local1 - - local2 - - local3 - - local4 - - local5 - - local6 - - local7 + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. type: string - port: - description: port is the UDP port number of the syslog - endpoint that receives log messages. - format: int32 - maximum: 65535 - minimum: 1 - type: integer + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array required: - - address - - port + - key + - operator type: object - type: - description: "type is the type of destination for logs. - \ It must be one of the following: \n * Container \n The - ingress operator configures the sidecar container named - \"logs\" on the ingress controller pod and configures - the ingress controller to write logs to the sidecar. The - logs are then available as container logs. The expectation - is that the administrator configures a custom logging - solution that reads logs from this sidecar. Note that - using container logs means that logs may be dropped if - the rate of logs exceeds the container runtime's or the - custom logging solution's capacity. \n * Syslog \n Logs - are sent to a syslog endpoint. The administrator must - specify an endpoint that can receive syslog messages. - \ The expectation is that the administrator has configured - a custom syslog instance." - enum: - - Container - - Syslog + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + tolerations: + description: "tolerations is a list of tolerations applied to + ingress controller deployments. \n The default is an empty list. + \n See https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/" + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + replicas: + description: replicas is the desired number of ingress controller + replicas. If unset, defaults to 2. + format: int32 + type: integer + routeAdmission: + description: "routeAdmission defines a policy for handling new route + claims (for example, to allow or deny claims across namespaces). + \n If empty, defaults will be applied. See specific routeAdmission + fields for details about their defaults." + properties: + namespaceOwnership: + description: "namespaceOwnership describes how host name claims + across namespaces should be handled. \n Value must be one of: + \n - Strict: Do not allow routes in different namespaces to + claim the same host. \n - InterNamespaceAllowed: Allow routes + to claim different paths of the same host name across namespaces. + \n If empty, the default is Strict." + enum: + - InterNamespaceAllowed + - Strict + type: string + wildcardPolicy: + description: "wildcardPolicy describes how routes with wildcard + policies should be handled for the ingress controller. WildcardPolicy + controls use of routes [1] exposed by the ingress controller + based on the route's wildcard policy. \n [1] https://github.com/openshift/api/blob/master/route/v1/types.go + \n Note: Updating WildcardPolicy from WildcardsAllowed to WildcardsDisallowed + will cause admitted routes with a wildcard policy of Subdomain + to stop working. These routes must be updated to a wildcard + policy of None to be readmitted by the ingress controller. \n + WildcardPolicy supports WildcardsAllowed and WildcardsDisallowed + values. \n If empty, defaults to \"WildcardsDisallowed\"." + enum: + - WildcardsAllowed + - WildcardsDisallowed + type: string + type: object + routeSelector: + description: "routeSelector is used to filter the set of Routes serviced + by the ingress controller. This is useful for implementing shards. + \n If unset, the default is no filtering." + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array required: - - type + - key + - operator type: object - httpLogFormat: - description: "httpLogFormat specifies the format of the log - message for an HTTP request. \n If this field is empty, log - messages use the implementation's default HTTP log format. - \ For HAProxy's default HTTP log format, see the HAProxy documentation: - http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3" + type: array + matchLabels: + additionalProperties: type: string - required: - - destination - type: object - type: object - namespaceSelector: - description: "namespaceSelector is used to filter the set of namespaces - serviced by the ingress controller. This is useful for implementing - shards. \n If unset, the default is no filtering." - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that contains - values, a key, and an operator that relates the key and values. + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + tlsSecurityProfile: + description: "tlsSecurityProfile specifies settings for TLS connections + for ingresscontrollers. \n If unset, the default is based on the + apiservers.config.openshift.io/cluster resource. \n Note that when + using the Old, Intermediate, and Modern profile types, the effective + profile configuration is subject to change between releases. For + example, given a specification to use the Intermediate profile deployed + on release X.Y.Z, an upgrade to release X.Y.Z+1 may cause a new + profile configuration to be applied to the ingress controller, resulting + in a rollout. \n Note that the minimum TLS version for ingress controllers + is 1.1, and the maximum TLS version is 1.2. An implication of this + restriction is that the Modern TLS profile type cannot be used because + it requires TLS 1.3." + properties: + custom: + description: "custom is a user-defined TLS security profile. Be + extremely careful using a custom profile as invalid configurations + can be catastrophic. An example custom profile looks like this: + \n ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 + \ - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 + \ minTLSVersion: TLSv1.1" + nullable: true properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to a - set of values. Valid operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string values. If the operator - is In or NotIn, the values array must be non-empty. If the - operator is Exists or DoesNotExist, the values array must - be empty. This array is replaced during a strategic merge - patch. + ciphers: + description: "ciphers is used to specify the cipher algorithms + that are negotiated during the TLS handshake. Operators + may remove entries their operands do not support. For example, + to use DES-CBC3-SHA (yaml): \n ciphers: - DES-CBC3-SHA" items: type: string type: array - required: - - key - - operator + minTLSVersion: + description: "minTLSVersion is used to specify the minimal + version of the TLS protocol that is negotiated during the + TLS handshake. For example, to use TLS versions 1.1, 1.2 + and 1.3 (yaml): \n minTLSVersion: TLSv1.1 \n NOTE: currently + the highest minTLSVersion allowed is VersionTLS12" + enum: + - VersionTLS10 + - VersionTLS11 + - VersionTLS12 + - VersionTLS13 + type: string type: object - type: array - matchLabels: - additionalProperties: + intermediate: + description: "intermediate is a TLS security profile based on: + \n https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29 + \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 + \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 + \ - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 + \ - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 + \ - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 + \ - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 + \ minTLSVersion: TLSv1.2" + nullable: true + type: object + modern: + description: "modern is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility + \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 + \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 + \ minTLSVersion: TLSv1.3 \n NOTE: Currently unsupported." + nullable: true + type: object + old: + description: "old is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility + \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 + \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 + \ - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 + \ - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 + \ - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 + \ - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 + \ - DHE-RSA-CHACHA20-POLY1305 - ECDHE-ECDSA-AES128-SHA256 + \ - ECDHE-RSA-AES128-SHA256 - ECDHE-ECDSA-AES128-SHA + \ - ECDHE-RSA-AES128-SHA - ECDHE-ECDSA-AES256-SHA384 + \ - ECDHE-RSA-AES256-SHA384 - ECDHE-ECDSA-AES256-SHA + \ - ECDHE-RSA-AES256-SHA - DHE-RSA-AES128-SHA256 - + DHE-RSA-AES256-SHA256 - AES128-GCM-SHA256 - AES256-GCM-SHA384 + \ - AES128-SHA256 - AES256-SHA256 - AES128-SHA - + AES256-SHA - DES-CBC3-SHA minTLSVersion: TLSv1.0" + nullable: true + type: object + type: + description: "type is one of Old, Intermediate, Modern or Custom. + Custom provides the ability to specify individual TLS security + profile parameters. Old, Intermediate and Modern are TLS security + profiles based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations + \n The profiles are intent based, so they may change over time + as new ciphers are developed and existing ciphers are found + to be insecure. Depending on precisely which ciphers are available + to a process, the list may be reduced. \n Note that the Modern + profile is currently not supported because it is not yet well + adopted by common software libraries." + enum: + - Old + - Intermediate + - Modern + - Custom type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator is - "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - nodePlacement: - description: "nodePlacement enables explicit control over the scheduling - of the ingress controller. \n If unset, defaults are used. See NodePlacement - for more details." - properties: - nodeSelector: - description: "nodeSelector is the node selector applied to ingress - controller deployments. \n If unset, the default is: \n beta.kubernetes.io/os: - linux node-role.kubernetes.io/worker: '' \n If set, the specified - selector is used and replaces the default." + type: object + type: object + status: + description: status is the most recently observed status of the IngressController. + properties: + availableReplicas: + description: availableReplicas is number of observed available replicas + according to the ingress controller deployment. + format: int32 + type: integer + conditions: + description: "conditions is a list of conditions and their status. + \n Available means the ingress controller deployment is available + and servicing route and ingress resources (i.e, .status.availableReplicas + equals .spec.replicas) \n There are additional conditions which + indicate the status of other ingress controller features and capabilities. + \n * LoadBalancerManaged - True if the following conditions + are met: * The endpoint publishing strategy requires a service + load balancer. - False if any of those conditions are unsatisfied. + \n * LoadBalancerReady - True if the following conditions are + met: * A load balancer is managed. * The load balancer is + ready. - False if any of those conditions are unsatisfied. \n + \ * DNSManaged - True if the following conditions are met: * + The endpoint publishing strategy and platform support DNS. * + The ingress controller domain is set. * dns.config.openshift.io/cluster + configures DNS zones. - False if any of those conditions are unsatisfied. + \n * DNSReady - True if the following conditions are met: * + DNS is managed. * DNS records have been successfully created. + \ - False if any of those conditions are unsatisfied." + items: + description: OperatorCondition is just the standard condition fields. properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + domain: + description: domain is the actual domain in use. + type: string + endpointPublishingStrategy: + description: endpointPublishingStrategy is the actual strategy in + use. + properties: + hostNetwork: + description: hostNetwork holds parameters for the HostNetwork + endpoint publishing strategy. Present only if type is HostNetwork. + type: object + loadBalancer: + description: loadBalancer holds parameters for the load balancer. + Present only if type is LoadBalancerService. + properties: + providerParameters: + description: "providerParameters holds desired load balancer + information specific to the underlying infrastructure provider. + \n If empty, defaults will be applied. See specific providerParameters + fields for details about their defaults." properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. + aws: + description: "aws provides configuration settings that + are specific to AWS load balancers. \n If empty, defaults + will be applied. See specific aws fields for details + about their defaults." + properties: + classicLoadBalancer: + description: classicLoadBalancerParameters holds configuration + parameters for an AWS classic load balancer. Present + only if type is Classic. + type: object + networkLoadBalancer: + description: networkLoadBalancerParameters holds configuration + parameters for an AWS network load balancer. Present + only if type is NLB. + type: object + type: + description: "type is the type of AWS load balancer + to instantiate for an ingresscontroller. \n Valid + values are: \n * \"Classic\": A Classic Load Balancer + that makes routing decisions at either the transport + layer (TCP/SSL) or the application layer (HTTP/HTTPS). + See the following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + \n * \"NLB\": A Network Load Balancer that makes + routing decisions at the transport layer (TCP/SSL). + See the following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb" + enum: + - Classic + - NLB + type: string + required: + - type + type: object + type: + description: type is the underlying infrastructure provider + for the load balancer. Allowed values are "AWS", "Azure", + "BareMetal", "GCP", "OpenStack", and "VSphere". + enum: + - AWS + - Azure + - BareMetal + - GCP + - OpenStack + - VSphere + - IBM type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array required: - - key - - operator + - type type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - tolerations: - description: "tolerations is a list of tolerations applied to ingress - controller deployments. \n The default is an empty list. \n See - https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/" - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using the - matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to the - value. Valid operators are Exists and Equal. Defaults to - Equal. Exists is equivalent to wildcard for value, so that - a pod can tolerate all taints of a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of time - the toleration (which must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint forever (do - not evict). Zero and negative values will be treated as - 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + scope: + description: scope indicates the scope at which the load balancer + is exposed. Possible values are "External" and "Internal". + enum: + - Internal + - External type: string - type: object - type: array - type: object - replicas: - description: replicas is the desired number of ingress controller replicas. - If unset, defaults to 2. - format: int32 - type: integer - routeAdmission: - description: "routeAdmission defines a policy for handling new route - claims (for example, to allow or deny claims across namespaces). \n - If empty, defaults will be applied. See specific routeAdmission fields - for details about their defaults." - properties: - namespaceOwnership: - description: "namespaceOwnership describes how host name claims - across namespaces should be handled. \n Value must be one of: - \n - Strict: Do not allow routes in different namespaces to claim - the same host. \n - InterNamespaceAllowed: Allow routes to claim - different paths of the same host name across namespaces. \n - If empty, the default is Strict." - enum: - - InterNamespaceAllowed - - Strict - type: string - wildcardPolicy: - description: "wildcardPolicy describes how routes with wildcard - policies should be handled for the ingress controller. WildcardPolicy - controls use of routes [1] exposed by the ingress controller based - on the route's wildcard policy. \n [1] https://github.com/openshift/api/blob/master/route/v1/types.go - \n Note: Updating WildcardPolicy from WildcardsAllowed to WildcardsDisallowed - will cause admitted routes with a wildcard policy of Subdomain - to stop working. These routes must be updated to a wildcard policy - of None to be readmitted by the ingress controller. \n WildcardPolicy - supports WildcardsAllowed and WildcardsDisallowed values. \n If - empty, defaults to \"WildcardsDisallowed\"." - enum: - - WildcardsAllowed - - WildcardsDisallowed - type: string - type: object - routeSelector: - description: "routeSelector is used to filter the set of Routes serviced - by the ingress controller. This is useful for implementing shards. - \n If unset, the default is no filtering." - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that contains - values, a key, and an operator that relates the key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to a - set of values. Valid operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string values. If the operator - is In or NotIn, the values array must be non-empty. If the - operator is Exists or DoesNotExist, the values array must - be empty. This array is replaced during a strategic merge - patch. - items: - type: string - type: array required: - - key - - operator + - scope + type: object + nodePort: + description: nodePort holds parameters for the NodePortService + endpoint publishing strategy. Present only if type is NodePortService. + type: object + private: + description: private holds parameters for the Private endpoint + publishing strategy. Present only if type is Private. type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator is - "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - tlsSecurityProfile: - description: "tlsSecurityProfile specifies settings for TLS connections - for ingresscontrollers. \n If unset, the default is based on the apiservers.config.openshift.io/cluster - resource. \n Note that when using the Old, Intermediate, and Modern - profile types, the effective profile configuration is subject to change - between releases. For example, given a specification to use the Intermediate - profile deployed on release X.Y.Z, an upgrade to release X.Y.Z+1 may - cause a new profile configuration to be applied to the ingress controller, - resulting in a rollout. \n Note that the minimum TLS version for ingress - controllers is 1.1, and the maximum TLS version is 1.2. An implication - of this restriction is that the Modern TLS profile type cannot be - used because it requires TLS 1.3." - properties: - custom: - description: "custom is a user-defined TLS security profile. Be - extremely careful using a custom profile as invalid configurations - can be catastrophic. An example custom profile looks like this: - \n ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - \ - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 - \ minTLSVersion: TLSv1.1" - nullable: true - properties: - ciphers: - description: "ciphers is used to specify the cipher algorithms - that are negotiated during the TLS handshake. Operators may - remove entries their operands do not support. For example, - to use DES-CBC3-SHA (yaml): \n ciphers: - DES-CBC3-SHA" - items: - type: string - type: array - minTLSVersion: - description: "minTLSVersion is used to specify the minimal version - of the TLS protocol that is negotiated during the TLS handshake. - For example, to use TLS versions 1.1, 1.2 and 1.3 (yaml): - \n minTLSVersion: TLSv1.1 \n NOTE: currently the highest - minTLSVersion allowed is VersionTLS12" - enum: - - VersionTLS10 - - VersionTLS11 - - VersionTLS12 - - VersionTLS13 - type: string - type: object - intermediate: - description: "intermediate is a TLS security profile based on: \n - https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29 - \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - \ - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - \ - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - \ - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - \ - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 - \ minTLSVersion: TLSv1.2" - nullable: true - type: object - modern: - description: "modern is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility - \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - \ minTLSVersion: TLSv1.3 \n NOTE: Currently unsupported." - nullable: true - type: object - old: - description: "old is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility - \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256 - \ - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - \ - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - \ - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - \ - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 - \ - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 - \ - DHE-RSA-CHACHA20-POLY1305 - ECDHE-ECDSA-AES128-SHA256 - \ - ECDHE-RSA-AES128-SHA256 - ECDHE-ECDSA-AES128-SHA - - ECDHE-RSA-AES128-SHA - ECDHE-ECDSA-AES256-SHA384 - ECDHE-RSA-AES256-SHA384 - \ - ECDHE-ECDSA-AES256-SHA - ECDHE-RSA-AES256-SHA - - DHE-RSA-AES128-SHA256 - DHE-RSA-AES256-SHA256 - AES128-GCM-SHA256 - \ - AES256-GCM-SHA384 - AES128-SHA256 - AES256-SHA256 - \ - AES128-SHA - AES256-SHA - DES-CBC3-SHA minTLSVersion: - TLSv1.0" - nullable: true - type: object - type: - description: "type is one of Old, Intermediate, Modern or Custom. - Custom provides the ability to specify individual TLS security - profile parameters. Old, Intermediate and Modern are TLS security - profiles based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations - \n The profiles are intent based, so they may change over time - as new ciphers are developed and existing ciphers are found to - be insecure. Depending on precisely which ciphers are available - to a process, the list may be reduced. \n Note that the Modern - profile is currently not supported because it is not yet well - adopted by common software libraries." - enum: - - Old - - Intermediate - - Modern - - Custom - type: string - type: object - type: object - status: - description: status is the most recently observed status of the IngressController. - properties: - availableReplicas: - description: availableReplicas is number of observed available replicas - according to the ingress controller deployment. - format: int32 - type: integer - conditions: - description: "conditions is a list of conditions and their status. \n - Available means the ingress controller deployment is available and - servicing route and ingress resources (i.e, .status.availableReplicas - equals .spec.replicas) \n There are additional conditions which indicate - the status of other ingress controller features and capabilities. - \n * LoadBalancerManaged - True if the following conditions are - met: * The endpoint publishing strategy requires a service load - balancer. - False if any of those conditions are unsatisfied. \n - \ * LoadBalancerReady - True if the following conditions are met: - \ * A load balancer is managed. * The load balancer is ready. - \ - False if any of those conditions are unsatisfied. \n * DNSManaged - \ - True if the following conditions are met: * The endpoint - publishing strategy and platform support DNS. * The ingress controller - domain is set. * dns.config.openshift.io/cluster configures DNS - zones. - False if any of those conditions are unsatisfied. \n * - DNSReady - True if the following conditions are met: * DNS is - managed. * DNS records have been successfully created. - False - if any of those conditions are unsatisfied." - items: - description: OperatorCondition is just the standard condition fields. - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string type: + description: "type is the publishing strategy to use. Valid values + are: \n * LoadBalancerService \n Publishes the ingress controller + using a Kubernetes LoadBalancer Service. \n In this configuration, + the ingress controller deployment uses container networking. + A LoadBalancer Service is created to publish the deployment. + \n See: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer + \n If domain is set, a wildcard DNS record will be managed to + point at the LoadBalancer Service's external name. DNS records + are managed only in DNS zones defined by dns.config.openshift.io/cluster + .spec.publicZone and .spec.privateZone. \n Wildcard DNS management + is currently supported only on the AWS, Azure, and GCP platforms. + \n * HostNetwork \n Publishes the ingress controller on node + ports where the ingress controller is deployed. \n In this configuration, + the ingress controller deployment uses host networking, bound + to node ports 80 and 443. The user is responsible for configuring + an external load balancer to publish the ingress controller + via the node ports. \n * Private \n Does not publish the ingress + controller. \n In this configuration, the ingress controller + deployment uses container networking, and is not explicitly + published. The user must manually publish the ingress controller. + \n * NodePortService \n Publishes the ingress controller using + a Kubernetes NodePort Service. \n In this configuration, the + ingress controller deployment uses container networking. A NodePort + Service is created to publish the deployment. The specific node + ports are dynamically allocated by OpenShift; however, to support + static port allocations, user changes to the node port field + of the managed NodePort Service will preserved." + enum: + - LoadBalancerService + - HostNetwork + - Private + - NodePortService type: string + required: + - type type: object - type: array - domain: - description: domain is the actual domain in use. - type: string - endpointPublishingStrategy: - description: endpointPublishingStrategy is the actual strategy in use. - properties: - hostNetwork: - description: hostNetwork holds parameters for the HostNetwork endpoint - publishing strategy. Present only if type is HostNetwork. - type: object - loadBalancer: - description: loadBalancer holds parameters for the load balancer. - Present only if type is LoadBalancerService. - properties: - providerParameters: - description: "providerParameters holds desired load balancer - information specific to the underlying infrastructure provider. - \n If empty, defaults will be applied. See specific providerParameters - fields for details about their defaults." - properties: - aws: - description: "aws provides configuration settings that are - specific to AWS load balancers. \n If empty, defaults - will be applied. See specific aws fields for details about - their defaults." - properties: - classicLoadBalancer: - description: classicLoadBalancerParameters holds configuration - parameters for an AWS classic load balancer. Present - only if type is Classic. - type: object - networkLoadBalancer: - description: networkLoadBalancerParameters holds configuration - parameters for an AWS network load balancer. Present - only if type is NLB. - type: object - type: - description: "type is the type of AWS load balancer - to instantiate for an ingresscontroller. \n Valid - values are: \n * \"Classic\": A Classic Load Balancer - that makes routing decisions at either the transport - layer (TCP/SSL) or the application layer (HTTP/HTTPS). - See the following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb - \n * \"NLB\": A Network Load Balancer that makes routing - decisions at the transport layer (TCP/SSL). See - the following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb" - enum: - - Classic - - NLB - type: string - required: - - type - type: object - type: - description: type is the underlying infrastructure provider - for the load balancer. Allowed values are "AWS", "Azure", - "BareMetal", "GCP", "OpenStack", and "VSphere". - enum: - - AWS - - Azure - - BareMetal - - GCP - - OpenStack - - VSphere - type: string - required: - - type - type: object - scope: - description: scope indicates the scope at which the load balancer - is exposed. Possible values are "External" and "Internal". - enum: - - Internal - - External + observedGeneration: + description: observedGeneration is the most recent generation observed. + format: int64 + type: integer + selector: + description: selector is a label selector, in string format, for ingress + controller pods corresponding to the IngressController. The number + of matching pods should equal the value of availableReplicas. + type: string + tlsProfile: + description: tlsProfile is the TLS connection configuration that is + in effect. + properties: + ciphers: + description: "ciphers is used to specify the cipher algorithms + that are negotiated during the TLS handshake. Operators may + remove entries their operands do not support. For example, + to use DES-CBC3-SHA (yaml): \n ciphers: - DES-CBC3-SHA" + items: type: string - required: - - scope - type: object - nodePort: - description: nodePort holds parameters for the NodePortService endpoint - publishing strategy. Present only if type is NodePortService. - type: object - private: - description: private holds parameters for the Private endpoint publishing - strategy. Present only if type is Private. - type: object - type: - description: "type is the publishing strategy to use. Valid values - are: \n * LoadBalancerService \n Publishes the ingress controller - using a Kubernetes LoadBalancer Service. \n In this configuration, - the ingress controller deployment uses container networking. A - LoadBalancer Service is created to publish the deployment. \n - See: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer - \n If domain is set, a wildcard DNS record will be managed to - point at the LoadBalancer Service's external name. DNS records - are managed only in DNS zones defined by dns.config.openshift.io/cluster - .spec.publicZone and .spec.privateZone. \n Wildcard DNS management - is currently supported only on the AWS, Azure, and GCP platforms. - \n * HostNetwork \n Publishes the ingress controller on node ports - where the ingress controller is deployed. \n In this configuration, - the ingress controller deployment uses host networking, bound - to node ports 80 and 443. The user is responsible for configuring - an external load balancer to publish the ingress controller via - the node ports. \n * Private \n Does not publish the ingress controller. - \n In this configuration, the ingress controller deployment uses - container networking, and is not explicitly published. The user - must manually publish the ingress controller. \n * NodePortService - \n Publishes the ingress controller using a Kubernetes NodePort - Service. \n In this configuration, the ingress controller deployment - uses container networking. A NodePort Service is created to publish - the deployment. The specific node ports are dynamically allocated - by OpenShift; however, to support static port allocations, user - changes to the node port field of the managed NodePort Service - will preserved." - enum: - - LoadBalancerService - - HostNetwork - - Private - - NodePortService - type: string - required: - - type - type: object - observedGeneration: - description: observedGeneration is the most recent generation observed. - format: int64 - type: integer - selector: - description: selector is a label selector, in string format, for ingress - controller pods corresponding to the IngressController. The number - of matching pods should equal the value of availableReplicas. - type: string - tlsProfile: - description: tlsProfile is the TLS connection configuration that is - in effect. - properties: - ciphers: - description: "ciphers is used to specify the cipher algorithms that - are negotiated during the TLS handshake. Operators may remove - entries their operands do not support. For example, to use DES-CBC3-SHA - \ (yaml): \n ciphers: - DES-CBC3-SHA" - items: + type: array + minTLSVersion: + description: "minTLSVersion is used to specify the minimal version + of the TLS protocol that is negotiated during the TLS handshake. + For example, to use TLS versions 1.1, 1.2 and 1.3 (yaml): \n + \ minTLSVersion: TLSv1.1 \n NOTE: currently the highest minTLSVersion + allowed is VersionTLS12" + enum: + - VersionTLS10 + - VersionTLS11 + - VersionTLS12 + - VersionTLS13 type: string - type: array - minTLSVersion: - description: "minTLSVersion is used to specify the minimal version - of the TLS protocol that is negotiated during the TLS handshake. - For example, to use TLS versions 1.1, 1.2 and 1.3 (yaml): \n minTLSVersion: - TLSv1.1 \n NOTE: currently the highest minTLSVersion allowed is - VersionTLS12" - enum: - - VersionTLS10 - - VersionTLS11 - - VersionTLS12 - - VersionTLS13 - type: string - type: object - type: object - type: object - version: v1 - versions: - - name: v1 + type: object + type: object + type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml-merge-patch b/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml-merge-patch deleted file mode 100644 index 0439275bc309..000000000000 --- a/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml-merge-patch +++ /dev/null @@ -1,20 +0,0 @@ -spec: - validation: - openAPIV3Schema: - properties: - spec: - properties: - logging: - properties: - access: - properties: - destination: - properties: - syslog: - oneOf: - - properties: - address: - format: ipv4 - - properties: - address: - format: ipv6 diff --git a/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml-patch b/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml-patch new file mode 100644 index 000000000000..6076c3a31b81 --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/0000_50_ingress-operator_00-ingresscontroller.crd.yaml-patch @@ -0,0 +1,9 @@ +- op: add + path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/logging/properties/access/properties/destination/properties/syslog/oneOf + value: + - properties: + address: + format: ipv4 + - properties: + address: + format: ipv6 diff --git a/vendor/github.com/openshift/api/operator/v1/0000_50_service-ca-operator_02_crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_50_service-ca-operator_02_crd.yaml index c3349ff9706f..3f9f7b10a59a 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_50_service-ca-operator_02_crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_50_service-ca-operator_02_crd.yaml @@ -1,138 +1,139 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: servicecas.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: scope: Cluster - preserveUnknownFields: false group: operator.openshift.io - version: v1 - names: - kind: ServiceCA - plural: servicecas - singular: serviceca - subresources: - status: {} - validation: - openAPIV3Schema: - description: ServiceCA provides information to configure an operator to manage - the service cert controllers - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec holds user settable values for configuration - type: object - properties: - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - description: status holds observed values from the cluster. They may not - be overridden. - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: ServiceCA provides information to configure an operator to manage + the service cert controllers + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + type: object + properties: + logLevel: + description: logLevel is an intent based logging for an overall component. It + does not give fine grained control, but it is a simple way to manage + coarse grained logging choices that operators have to interpret + for their operands. + type: string + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + description: status holds observed values from the cluster. They may not + be overridden. + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01_crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01_crd.yaml index f738265ee314..0f16866957ca 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01_crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01_crd.yaml @@ -1,7 +1,9 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: networks.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: operator.openshift.io names: @@ -10,368 +12,374 @@ spec: plural: networks singular: network scope: Cluster - preserveUnknownFields: false versions: - name: v1 served: true storage: true - validation: - # Ensure we will be able to deserialize the object into the golang type - openAPIV3Schema: - description: Network describes the cluster's desired network configuration. - It is consumed by the cluster-network-operator. - type: object - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: NetworkSpec is the top-level network configuration object. - type: object - properties: - additionalNetworks: - description: additionalNetworks is a list of extra networks to make - available to pods when multiple networks are enabled. - type: array - items: - description: AdditionalNetworkDefinition configures an extra network - that is available but not created by default. Instead, pods must - request them by name. type must be specified, along with exactly - one "Config" that matches the type. + schema: + openAPIV3Schema: + description: Network describes the cluster's desired network configuration. + It is consumed by the cluster-network-operator. + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NetworkSpec is the top-level network configuration object. + type: object + properties: + additionalNetworks: + description: additionalNetworks is a list of extra networks to make + available to pods when multiple networks are enabled. + type: array + items: + description: AdditionalNetworkDefinition configures an extra network + that is available but not created by default. Instead, pods must + request them by name. type must be specified, along with exactly + one "Config" that matches the type. + type: object + properties: + name: + description: name is the name of the network. This will be populated + in the resulting CRD This must be unique. + type: string + namespace: + description: namespace is the namespace of the network. This + will be populated in the resulting CRD If not given the network + will be created in the default namespace. + type: string + rawCNIConfig: + description: rawCNIConfig is the raw CNI configuration json + to create in the NetworkAttachmentDefinition CRD + type: string + simpleMacvlanConfig: + description: SimpleMacvlanConfig configures the macvlan interface + in case of type:NetworkTypeSimpleMacvlan + type: object + properties: + ipamConfig: + description: IPAMConfig configures IPAM module will be used + for IP Address Management (IPAM). + type: object + properties: + staticIPAMConfig: + description: StaticIPAMConfig configures the static + IP address in case of type:IPAMTypeStatic + type: object + properties: + addresses: + description: Addresses configures IP address for + the interface + type: array + items: + description: StaticIPAMAddresses provides IP address + and Gateway for static IPAM addresses + type: object + properties: + address: + description: Address is the IP address in + CIDR format + type: string + gateway: + description: Gateway is IP inside of subnet + to designate as the gateway + type: string + dns: + description: DNS configures DNS for the interface + type: object + properties: + domain: + description: Domain configures the domainname + the local domain used for short hostname lookups + type: string + nameservers: + description: Nameservers points DNS servers + for IP lookup + type: array + items: + type: string + search: + description: Search configures priority ordered + search domains for short hostname lookups + type: array + items: + type: string + routes: + description: Routes configures IP routes for the + interface + type: array + items: + description: StaticIPAMRoutes provides Destination/Gateway + pairs for static IPAM routes + type: object + properties: + destination: + description: Destination points the IP route + destination + type: string + gateway: + description: Gateway is the route's next-hop + IP address If unset, a default gateway is + assumed (as determined by the CNI plugin). + type: string + type: + description: Type is the type of IPAM module will be + used for IP Address Management(IPAM). The supported + values are IPAMTypeDHCP, IPAMTypeStatic + type: string + master: + description: master is the host interface to create the + macvlan interface from. If not specified, it will be default + route interface + type: string + mode: + description: 'mode is the macvlan mode: bridge, private, + vepa, passthru. The default is bridge' + type: string + mtu: + description: mtu is the mtu to use for the macvlan interface. + if unset, host's kernel will select the value. + type: integer + format: int32 + minimum: 0 + type: + description: type is the type of network The supported values + are NetworkTypeRaw, NetworkTypeSimpleMacvlan + type: string + clusterNetwork: + description: clusterNetwork is the IP address pool to use for pod + IPs. Some network providers, e.g. OpenShift SDN, support multiple + ClusterNetworks. Others only support one. This is equivalent to + the cluster-cidr. + type: array + items: + description: ClusterNetworkEntry is a subnet from which to allocate + PodIPs. A network of size HostPrefix (in CIDR notation) will be + allocated when nodes join the cluster. If the HostPrefix field + is not used by the plugin, it can be left unset. Not all network + providers support multiple ClusterNetworks + type: object + properties: + cidr: + type: string + hostPrefix: + type: integer + format: int32 + minimum: 0 + defaultNetwork: + description: defaultNetwork is the "default" network that all pods + will receive type: object properties: - name: - description: name is the name of the network. This will be populated - in the resulting CRD This must be unique. - type: string - namespace: - description: namespace is the namespace of the network. This will - be populated in the resulting CRD If not given the network will - be created in the default namespace. - type: string - rawCNIConfig: - description: rawCNIConfig is the raw CNI configuration json to - create in the NetworkAttachmentDefinition CRD - type: string - simpleMacvlanConfig: - description: SimpleMacvlanConfig configures the macvlan interface - in case of type:NetworkTypeSimpleMacvlan + kuryrConfig: + description: KuryrConfig configures the kuryr plugin type: object properties: - ipamConfig: - description: IPAMConfig configures IPAM module will be used - for IP Address Management (IPAM). - type: object - properties: - staticIPAMConfig: - description: StaticIPAMConfig configures the static IP - address in case of type:IPAMTypeStatic - type: object - properties: - addresses: - description: Addresses configures IP address for the - interface - type: array - items: - description: StaticIPAMAddresses provides IP address - and Gateway for static IPAM addresses - type: object - properties: - address: - description: Address is the IP address in CIDR - format - type: string - gateway: - description: Gateway is IP inside of subnet - to designate as the gateway - type: string - dns: - description: DNS configures DNS for the interface - type: object - properties: - domain: - description: Domain configures the domainname - the local domain used for short hostname lookups - type: string - nameservers: - description: Nameservers points DNS servers for - IP lookup - type: array - items: - type: string - search: - description: Search configures priority ordered - search domains for short hostname lookups - type: array - items: - type: string - routes: - description: Routes configures IP routes for the interface - type: array - items: - description: StaticIPAMRoutes provides Destination/Gateway - pairs for static IPAM routes - type: object - properties: - destination: - description: Destination points the IP route - destination - type: string - gateway: - description: Gateway is the route's next-hop - IP address If unset, a default gateway is - assumed (as determined by the CNI plugin). - type: string - type: - description: Type is the type of IPAM module will be used - for IP Address Management(IPAM). The supported values - are IPAMTypeDHCP, IPAMTypeStatic - type: string - master: - description: master is the host interface to create the macvlan - interface from. If not specified, it will be default route - interface + controllerProbesPort: + description: The port kuryr-controller will listen for readiness + and liveness requests. + type: integer + format: int32 + minimum: 0 + daemonProbesPort: + description: The port kuryr-daemon will listen for readiness + and liveness requests. + type: integer + format: int32 + minimum: 0 + enablePortPoolsPrepopulation: + description: enablePortPoolsPrepopulation when true will make + Kuryr prepopulate each newly created port pool with a minimum + number of ports. Kuryr uses Neutron port pooling to fight + the fact that it takes a significant amount of time to create + one. Instead of creating it when pod is being deployed, + Kuryr keeps a number of ports ready to be attached to pods. + By default port prepopulation is disabled. + type: boolean + openStackServiceNetwork: + description: openStackServiceNetwork contains the CIDR of + network from which to allocate IPs for OpenStack Octavia's + Amphora VMs. Please note that with Amphora driver Octavia + uses two IPs from that network for each loadbalancer - one + given by OpenShift and second for VRRP connections. As the + first one is managed by OpenShift's and second by Neutron's + IPAMs, those need to come from different pools. Therefore + `openStackServiceNetwork` needs to be at least twice the + size of `serviceNetwork`, and whole `serviceNetwork` must + be overlapping with `openStackServiceNetwork`. cluster-network-operator + will then make sure VRRP IPs are taken from the ranges inside + `openStackServiceNetwork` that are not overlapping with + `serviceNetwork`, effectivly preventing conflicts. If not + set cluster-network-operator will use `serviceNetwork` expanded + by decrementing the prefix size by 1. type: string + poolBatchPorts: + description: poolBatchPorts sets a number of ports that should + be created in a single batch request to extend the port + pool. The default is 3. For more information about port + pools see enablePortPoolsPrepopulation setting. + type: integer + minimum: 0 + poolMaxPorts: + description: poolMaxPorts sets a maximum number of free ports + that are being kept in a port pool. If the number of ports + exceeds this setting, free ports will get deleted. Setting + 0 will disable this upper bound, effectively preventing + pools from shrinking and this is the default value. For + more information about port pools see enablePortPoolsPrepopulation + setting. + type: integer + minimum: 0 + poolMinPorts: + description: poolMinPorts sets a minimum number of free ports + that should be kept in a port pool. If the number of ports + is lower than this setting, new ports will get created and + added to pool. The default is 1. For more information about + port pools see enablePortPoolsPrepopulation setting. + type: integer + minimum: 1 + openshiftSDNConfig: + description: openShiftSDNConfig configures the openshift-sdn plugin + type: object + properties: + enableUnidling: + description: enableUnidling controls whether or not the service + proxy will support idling and unidling of services. By default, + unidling is enabled. + type: boolean mode: - description: 'mode is the macvlan mode: bridge, private, vepa, - passthru. The default is bridge' + description: mode is one of "Multitenant", "Subnet", or "NetworkPolicy" type: string mtu: - description: mtu is the mtu to use for the macvlan interface. - if unset, host's kernel will select the value. + description: mtu is the mtu to use for the tunnel interface. + Defaults to 1450 if unset. This must be 50 bytes smaller + than the machine's uplink. + type: integer + format: int32 + minimum: 0 + useExternalOpenvswitch: + description: useExternalOpenvswitch tells the operator not + to install openvswitch, because it will be provided separately. + If set, you must provide it yourself. + type: boolean + vxlanPort: + description: vxlanPort is the port to use for all vxlan packets. + The default is 4789. + type: integer + format: int32 + minimum: 0 + ovnKubernetesConfig: + description: oVNKubernetesConfig configures the ovn-kubernetes + plugin. This is currently not implemented. + type: object + properties: + genevePort: + description: geneve port is the UDP port to be used by geneve + encapulation. Default is 6081 + type: integer + format: int32 + minimum: 1 + hybridOverlayConfig: + description: HybridOverlayConfig configures an additional + overlay network for peers that are not using OVN. + type: object + properties: + hybridClusterNetwork: + description: HybridClusterNetwork defines a network space + given to nodes on an additional overlay network. + type: array + items: + description: ClusterNetworkEntry is a subnet from which + to allocate PodIPs. A network of size HostPrefix (in + CIDR notation) will be allocated when nodes join the + cluster. If the HostPrefix field is not used by the + plugin, it can be left unset. Not all network providers + support multiple ClusterNetworks + type: object + properties: + cidr: + type: string + hostPrefix: + type: integer + format: int32 + minimum: 0 + hybridOverlayVXLANPort: + description: HybridOverlayVXLANPort defines the VXLAN + port number to be used by the additional overlay network. + Default is 4789 + type: integer + format: int32 + mtu: + description: mtu is the MTU to use for the tunnel interface. + This must be 100 bytes smaller than the uplink mtu. Default + is 1400 type: integer format: int32 minimum: 0 type: - description: type is the type of network The supported values - are NetworkTypeRaw, NetworkTypeSimpleMacvlan + description: type is the type of network All NetworkTypes are + supported except for NetworkTypeRaw type: string - clusterNetwork: - description: clusterNetwork is the IP address pool to use for pod IPs. - Some network providers, e.g. OpenShift SDN, support multiple ClusterNetworks. - Others only support one. This is equivalent to the cluster-cidr. - type: array - items: - description: ClusterNetworkEntry is a subnet from which to allocate - PodIPs. A network of size HostPrefix (in CIDR notation) will be - allocated when nodes join the cluster. Not all network providers - support multiple ClusterNetworks + deployKubeProxy: + description: deployKubeProxy specifies whether or not a standalone + kube-proxy should be deployed by the operator. Some network providers + include kube-proxy or similar functionality. If unset, the plugin + will attempt to select the correct value, which is false when OpenShift + SDN and ovn-kubernetes are used and true otherwise. + type: boolean + disableMultiNetwork: + description: disableMultiNetwork specifies whether or not multiple + pod network support should be disabled. If unset, this property + defaults to 'false' and multiple network support is enabled. + type: boolean + kubeProxyConfig: + description: kubeProxyConfig lets us configure desired proxy configuration. + If not specified, sensible defaults will be chosen by OpenShift + directly. Not consumed by all network providers - currently only + openshift-sdn. type: object properties: - cidr: + bindAddress: + description: The address to "bind" on Defaults to 0.0.0.0 type: string - hostPrefix: - type: integer - format: int32 - minimum: 0 - defaultNetwork: - description: defaultNetwork is the "default" network that all pods will - receive - type: object - properties: - kuryrConfig: - description: KuryrConfig configures the kuryr plugin - type: object - properties: - controllerProbesPort: - description: The port kuryr-controller will listen for readiness - and liveness requests. - type: integer - format: int32 - minimum: 0 - daemonProbesPort: - description: The port kuryr-daemon will listen for readiness - and liveness requests. - type: integer - format: int32 - minimum: 0 - enablePortPoolsPrepopulation: - description: enablePortPoolsPrepopulation when true will make - Kuryr prepopulate each newly created port pool with a minimum - number of ports. Kuryr uses Neutron port pooling to fight - the fact that it takes a significant amount of time to create - one. Instead of creating it when pod is being deployed, Kuryr - keeps a number of ports ready to be attached to pods. By default - port prepopulation is disabled. - type: boolean - openStackServiceNetwork: - description: openStackServiceNetwork contains the CIDR of network - from which to allocate IPs for OpenStack Octavia's Amphora - VMs. Please note that with Amphora driver Octavia uses two - IPs from that network for each loadbalancer - one given by - OpenShift and second for VRRP connections. As the first one - is managed by OpenShift's and second by Neutron's IPAMs, those - need to come from different pools. Therefore `openStackServiceNetwork` - needs to be at least twice the size of `serviceNetwork`, and - whole `serviceNetwork` must be overlapping with `openStackServiceNetwork`. - cluster-network-operator will then make sure VRRP IPs are - taken from the ranges inside `openStackServiceNetwork` that - are not overlapping with `serviceNetwork`, effectivly preventing - conflicts. If not set cluster-network-operator will use `serviceNetwork` - expanded by decrementing the prefix size by 1. - type: string - poolBatchPorts: - description: poolBatchPorts sets a number of ports that should - be created in a single batch request to extend the port pool. - The default is 3. For more information about port pools see - enablePortPoolsPrepopulation setting. - type: integer - minimum: 0 - poolMaxPorts: - description: poolMaxPorts sets a maximum number of free ports - that are being kept in a port pool. If the number of ports - exceeds this setting, free ports will get deleted. Setting - 0 will disable this upper bound, effectively preventing pools - from shrinking and this is the default value. For more information - about port pools see enablePortPoolsPrepopulation setting. - type: integer - minimum: 0 - poolMinPorts: - description: poolMinPorts sets a minimum number of free ports - that should be kept in a port pool. If the number of ports - is lower than this setting, new ports will get created and - added to pool. The default is 1. For more information about - port pools see enablePortPoolsPrepopulation setting. - type: integer - minimum: 1 - openshiftSDNConfig: - description: openShiftSDNConfig configures the openshift-sdn plugin - type: object - properties: - enableUnidling: - description: enableUnidling controls whether or not the service - proxy will support idling and unidling of services. By default, - unidling is enabled. - type: boolean - mode: - description: mode is one of "Multitenant", "Subnet", or "NetworkPolicy" - type: string - mtu: - description: mtu is the mtu to use for the tunnel interface. - Defaults to 1450 if unset. This must be 50 bytes smaller than - the machine's uplink. - type: integer - format: int32 - minimum: 0 - useExternalOpenvswitch: - description: useExternalOpenvswitch tells the operator not to - install openvswitch, because it will be provided separately. - If set, you must provide it yourself. - type: boolean - vxlanPort: - description: vxlanPort is the port to use for all vxlan packets. - The default is 4789. - type: integer - format: int32 - minimum: 0 - ovnKubernetesConfig: - description: oVNKubernetesConfig configures the ovn-kubernetes plugin. - This is currently not implemented. - type: object - properties: - genevePort: - description: geneve port is the UDP port to be used by geneve - encapulation. Default is 6081 - type: integer - format: int32 - minimum: 1 - hybridOverlayConfig: - description: HybridOverlayConfig configures an additional overlay - network for peers that are not using OVN. - type: object - properties: - hybridClusterNetwork: - description: HybridClusterNetwork defines a network space - given to nodes on an additional overlay network. - type: array - items: - description: ClusterNetworkEntry is a subnet from which - to allocate PodIPs. A network of size HostPrefix (in - CIDR notation) will be allocated when nodes join the - cluster. Not all network providers support multiple - ClusterNetworks - type: object - properties: - cidr: - type: string - hostPrefix: - type: integer - format: int32 - minimum: 0 - hybridOverlayVXLANPort: - description: HybridOverlayVXLANPort defines the VXLAN port - number to be used by the additional overlay network. Default - is 4789 - type: integer - format: int32 - mtu: - description: mtu is the MTU to use for the tunnel interface. - This must be 100 bytes smaller than the uplink mtu. Default - is 1400 - type: integer - format: int32 - minimum: 0 - type: - description: type is the type of network All NetworkTypes are supported - except for NetworkTypeRaw - type: string - deployKubeProxy: - description: deployKubeProxy specifies whether or not a standalone kube-proxy - should be deployed by the operator. Some network providers include - kube-proxy or similar functionality. If unset, the plugin will attempt - to select the correct value, which is false when OpenShift SDN and - ovn-kubernetes are used and true otherwise. - type: boolean - disableMultiNetwork: - description: disableMultiNetwork specifies whether or not multiple pod - network support should be disabled. If unset, this property defaults - to 'false' and multiple network support is enabled. - type: boolean - kubeProxyConfig: - description: kubeProxyConfig lets us configure desired proxy configuration. - If not specified, sensible defaults will be chosen by OpenShift directly. - Not consumed by all network providers - currently only openshift-sdn. - type: object - properties: - bindAddress: - description: The address to "bind" on Defaults to 0.0.0.0 - type: string - iptablesSyncPeriod: - description: 'The period that iptables rules are refreshed. Default: - 30s' - type: string - proxyArguments: - description: Any additional arguments to pass to the kubeproxy process - type: object - additionalProperties: - description: ProxyArgumentList is a list of arguments to pass - to the kubeproxy process - type: array - items: - type: string - logLevel: - description: logLevel allows configuring the logging level of the components - deployed by the operator. Currently only Kuryr SDN is affected by - this setting. Please note that turning on extensive logging may affect - performance. The default value is "Normal". - type: string - serviceNetwork: - description: serviceNetwork is the ip address pool to use for Service - IPs Currently, all existing network providers only support a single - value here, but this is an array to allow for growth. - type: array - items: + iptablesSyncPeriod: + description: 'The period that iptables rules are refreshed. Default: + 30s' + type: string + proxyArguments: + description: Any additional arguments to pass to the kubeproxy + process + type: object + additionalProperties: + description: ProxyArgumentList is a list of arguments to pass + to the kubeproxy process + type: array + items: + type: string + logLevel: + description: logLevel allows configuring the logging level of the + components deployed by the operator. Currently only Kuryr SDN is + affected by this setting. Please note that turning on extensive + logging may affect performance. The default value is "Normal". type: string - status: - description: NetworkStatus is currently unused. Instead, status is reported - in the Network.config.openshift.io object. - type: object + serviceNetwork: + description: serviceNetwork is the ip address pool to use for Service + IPs Currently, all existing network providers only support a single + value here, but this is an array to allow for growth. + type: array + items: + type: string + status: + description: NetworkStatus is currently unused. Instead, status is reported + in the Network.config.openshift.io object. + type: object diff --git a/vendor/github.com/openshift/api/operator/v1/0000_70_console-operator.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_70_console-operator.crd.yaml index 5cabd510747b..f23db5fef21c 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_70_console-operator.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_70_console-operator.crd.yaml @@ -1,232 +1,237 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: consoles.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: scope: Cluster - preserveUnknownFields: false group: operator.openshift.io names: kind: Console listKind: ConsoleList plural: consoles singular: console - subresources: - status: {} versions: - name: v1 served: true storage: true - validation: - openAPIV3Schema: - description: Console provides a means to configure an operator to manage the - console. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ConsoleSpec is the specification of the desired behavior of - the Console. - type: object - properties: - customization: - description: customization is used to optionally provide a small set - of customization options to the web console. - type: object - properties: - brand: - description: brand is the default branding of the web console which - can be overridden by providing the brand field. There is a limited - set of specific brand options. This field controls elements of - the console such as the logo. Invalid value will prevent a console - rollout. - type: string - pattern: ^$|^(ocp|origin|okd|dedicated|online|azure)$ - customLogoFile: - description: 'customLogoFile replaces the default OpenShift logo - in the masthead and about dialog. It is a reference to a ConfigMap - in the openshift-config namespace. This can be created with a - command like ''oc create configmap custom-logo --from-file=/path/to/file - -n openshift-config''. Image size must be less than 1 MB due to - constraints on the ConfigMap size. The ConfigMap key should include - a file extension so that the console serves the file with the - correct MIME type. Recommended logo specifications: Dimensions: - Max height of 68px and max width of 200px SVG format preferred' + subresources: + status: {} + schema: + openAPIV3Schema: + description: Console provides a means to configure an operator to manage the + console. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConsoleSpec is the specification of the desired behavior + of the Console. + type: object + properties: + customization: + description: customization is used to optionally provide a small set + of customization options to the web console. + type: object + properties: + brand: + description: brand is the default branding of the web console + which can be overridden by providing the brand field. There + is a limited set of specific brand options. This field controls + elements of the console such as the logo. Invalid value will + prevent a console rollout. + type: string + pattern: ^$|^(ocp|origin|okd|dedicated|online|azure)$ + customLogoFile: + description: 'customLogoFile replaces the default OpenShift logo + in the masthead and about dialog. It is a reference to a ConfigMap + in the openshift-config namespace. This can be created with + a command like ''oc create configmap custom-logo --from-file=/path/to/file + -n openshift-config''. Image size must be less than 1 MB due + to constraints on the ConfigMap size. The ConfigMap key should + include a file extension so that the console serves the file + with the correct MIME type. Recommended logo specifications: + Dimensions: Max height of 68px and max width of 200px SVG format + preferred' + type: object + properties: + key: + description: Key allows pointing to a specific key/value inside + of the configmap. This is useful for logical file references. + type: string + name: + type: string + customProductName: + description: customProductName is the name that will be displayed + in page titles, logo alt text, and the about dialog instead + of the normal OpenShift product name. + type: string + documentationBaseURL: + description: documentationBaseURL links to external documentation + are shown in various sections of the web console. Providing + documentationBaseURL will override the default documentation + URL. Invalid value will prevent a console rollout. + type: string + pattern: ^$|^((https):\/\/?)[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/?))\/$ + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + type: object + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + providers: + description: providers contains configuration for using specific service + providers. + type: object + properties: + statuspage: + description: statuspage contains ID for statuspage.io page that + provides status info about. + type: object + properties: + pageID: + description: pageID is the unique ID assigned by Statuspage + for your page. This must be a public page. + type: string + route: + description: route contains hostname and secret reference that contains + the serving certificate. If a custom route is specified, a new route + will be created with the provided hostname, under which console + will be available. In case of custom hostname uses the default routing + suffix of the cluster, the Secret specification for a serving certificate + will not be needed. In case of custom hostname points to an arbitrary + domain, manual DNS configurations steps are necessary. The default + console route will be maintained to reserve the default hostname + for console if the custom route is removed. If not specified, default + route will be used. + type: object + properties: + hostname: + description: hostname is the desired custom domain under which + console will be available. + type: string + secret: + description: 'secret points to secret in the openshift-config + namespace that contains custom certificate and key and needs + to be created manually by the cluster admin. Referenced Secret + is required to contain following key value pairs: - "tls.crt" + - to specifies custom certificate - "tls.key" - to specifies + private key of the custom certificate If the custom hostname + uses the default routing suffix of the cluster, the Secret specification + for a serving certificate will not be needed.' + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced secret + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' + type: object + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + description: ConsoleStatus defines the observed status of the Console. + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. type: object properties: - key: - description: Key allows pointing to a specific key/value inside - of the configmap. This is useful for logical file references. + lastTransitionTime: type: string - name: + format: date-time + message: type: string - customProductName: - description: customProductName is the name that will be displayed - in page titles, logo alt text, and the about dialog instead of - the normal OpenShift product name. - type: string - documentationBaseURL: - description: documentationBaseURL links to external documentation - are shown in various sections of the web console. Providing documentationBaseURL - will override the default documentation URL. Invalid value will - prevent a console rollout. - type: string - pattern: ^$|^((https):\/\/?)[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/?))\/$ - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - providers: - description: providers contains configuration for using specific service - providers. - type: object - properties: - statuspage: - description: statuspage contains ID for statuspage.io page that - provides status info about. - type: object - properties: - pageID: - description: pageID is the unique ID assigned by Statuspage - for your page. This must be a public page. + reason: + type: string + status: type: string - route: - description: route contains hostname and secret reference that contains - the serving certificate. If a custom route is specified, a new route - will be created with the provided hostname, under which console will - be available. In case of custom hostname uses the default routing - suffix of the cluster, the Secret specification for a serving certificate - will not be needed. In case of custom hostname points to an arbitrary - domain, manual DNS configurations steps are necessary. The default - console route will be maintained to reserve the default hostname for - console if the custom route is removed. If not specified, default - route will be used. - type: object - properties: - hostname: - description: hostname is the desired custom domain under which console - will be available. - type: string - secret: - description: 'secret points to secret in the openshift-config namespace - that contains custom certificate and key and needs to be created - manually by the cluster admin. Referenced Secret is required to - contain following key value pairs: - "tls.crt" - to specifies - custom certificate - "tls.key" - to specifies private key of the - custom certificate If the custom hostname uses the default routing - suffix of the cluster, the Secret specification for a serving - certificate will not be needed.' + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. type: object - required: - - name properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 name: - description: name is the metadata.name of the referenced secret + description: name is the name of the thing you're tracking type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - description: ConsoleStatus defines the observed status of the Console. - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. - type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. - type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_70_dns-operator_00-custom-resource-definition.yaml b/vendor/github.com/openshift/api/operator/v1/0000_70_dns-operator_00-custom-resource-definition.yaml index e553f1f656f8..09bb779084ca 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_70_dns-operator_00-custom-resource-definition.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_70_dns-operator_00-custom-resource-definition.yaml @@ -1,8 +1,9 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - creationTimestamp: null name: dnses.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: operator.openshift.io names: @@ -11,132 +12,125 @@ spec: plural: dnses singular: dns scope: Cluster - preserveUnknownFields: false - subresources: - status: {} - validation: - openAPIV3Schema: - description: "DNS manages the CoreDNS component to provide a name resolution - service for pods and services in the cluster. \n This supports the DNS-based - service discovery specification: https://github.com/kubernetes/dns/blob/master/docs/specification.md - \n More details: https://kubernetes.io/docs/tasks/administer-cluster/coredns" - type: object - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec is the specification of the desired behavior of the DNS. - type: object - properties: - servers: - description: "servers is a list of DNS resolvers that provide name query - delegation for one or more subdomains outside the scope of the cluster - domain. If servers consists of more than one Server, longest suffix - match will be used to determine the Server. \n For example, if there - are two Servers, one for \"foo.com\" and another for \"a.foo.com\", - and the name query is for \"www.a.foo.com\", it will be routed to - the Server with Zone \"a.foo.com\". \n If this field is nil, no servers - are created." - type: array - items: - description: Server defines the schema for a server that runs per - instance of CoreDNS. - type: object - properties: - forwardPlugin: - description: forwardPlugin defines a schema for configuring CoreDNS - to proxy DNS messages to upstream resolvers. - type: object - properties: - upstreams: - description: "upstreams is a list of resolvers to forward - name queries for subdomains of Zones. Upstreams are randomized - when more than 1 upstream is specified. Each instance of - CoreDNS performs health checking of Upstreams. When a healthy - upstream returns an error during the exchange, another resolver - is tried from Upstreams. Each upstream is represented by - an IP address or IP:port if the upstream listens on a port - other than 53. \n A maximum of 15 upstreams is allowed per - ForwardPlugin." - type: array - maxItems: 15 - items: - type: string - name: - description: name is required and specifies a unique name for - the server. Name must comply with the Service Name Syntax of - rfc6335. - type: string - zones: - description: zones is required and specifies the subdomains that - Server is authoritative for. Zones must conform to the rfc1123 - definition of a subdomain. Specifying the cluster domain (i.e., - "cluster.local") is invalid. - type: array - items: - type: string - status: - description: status is the most recently observed status of the DNS. - type: object - required: - - clusterDomain - - clusterIP - properties: - clusterDomain: - description: "clusterDomain is the local cluster DNS domain suffix for - DNS services. This will be a subdomain as defined in RFC 1034, section - 3.5: https://tools.ietf.org/html/rfc1034#section-3.5 Example: \"cluster.local\" - \n More info: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service" - type: string - clusterIP: - description: "clusterIP is the service IP through which this DNS is - made available. \n In the case of the default DNS, this will be a - well known IP that is used as the default nameserver for pods that - are using the default ClusterFirst DNS policy. \n In general, this - IP can be specified in a pod's spec.dnsConfig.nameservers list or - used explicitly when performing name resolution from within the cluster. - Example: dig foo.com @ \n More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies" - type: string - conditions: - description: "conditions provide information about the state of the - DNS on the cluster. \n These are the supported DNS conditions: \n - \ * Available - True if the following conditions are met: * - DNS controller daemonset is available. - False if any of those conditions - are unsatisfied." - type: array - items: - description: OperatorCondition is just the standard condition fields. - type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - version: v1 versions: - name: v1 served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] + subresources: + status: {} + schema: + openAPIV3Schema: + description: "DNS manages the CoreDNS component to provide a name resolution + service for pods and services in the cluster. \n This supports the DNS-based + service discovery specification: https://github.com/kubernetes/dns/blob/master/docs/specification.md + \n More details: https://kubernetes.io/docs/tasks/administer-cluster/coredns" + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the specification of the desired behavior of the + DNS. + type: object + properties: + servers: + description: "servers is a list of DNS resolvers that provide name + query delegation for one or more subdomains outside the scope of + the cluster domain. If servers consists of more than one Server, + longest suffix match will be used to determine the Server. \n For + example, if there are two Servers, one for \"foo.com\" and another + for \"a.foo.com\", and the name query is for \"www.a.foo.com\", + it will be routed to the Server with Zone \"a.foo.com\". \n If this + field is nil, no servers are created." + type: array + items: + description: Server defines the schema for a server that runs per + instance of CoreDNS. + type: object + properties: + forwardPlugin: + description: forwardPlugin defines a schema for configuring + CoreDNS to proxy DNS messages to upstream resolvers. + type: object + properties: + upstreams: + description: "upstreams is a list of resolvers to forward + name queries for subdomains of Zones. Upstreams are randomized + when more than 1 upstream is specified. Each instance + of CoreDNS performs health checking of Upstreams. When + a healthy upstream returns an error during the exchange, + another resolver is tried from Upstreams. Each upstream + is represented by an IP address or IP:port if the upstream + listens on a port other than 53. \n A maximum of 15 upstreams + is allowed per ForwardPlugin." + type: array + maxItems: 15 + items: + type: string + name: + description: name is required and specifies a unique name for + the server. Name must comply with the Service Name Syntax + of rfc6335. + type: string + zones: + description: zones is required and specifies the subdomains + that Server is authoritative for. Zones must conform to the + rfc1123 definition of a subdomain. Specifying the cluster + domain (i.e., "cluster.local") is invalid. + type: array + items: + type: string + status: + description: status is the most recently observed status of the DNS. + type: object + required: + - clusterDomain + - clusterIP + properties: + clusterDomain: + description: "clusterDomain is the local cluster DNS domain suffix + for DNS services. This will be a subdomain as defined in RFC 1034, + section 3.5: https://tools.ietf.org/html/rfc1034#section-3.5 Example: + \"cluster.local\" \n More info: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service" + type: string + clusterIP: + description: "clusterIP is the service IP through which this DNS is + made available. \n In the case of the default DNS, this will be + a well known IP that is used as the default nameserver for pods + that are using the default ClusterFirst DNS policy. \n In general, + this IP can be specified in a pod's spec.dnsConfig.nameservers list + or used explicitly when performing name resolution from within the + cluster. Example: dig foo.com @ \n More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies" + type: string + conditions: + description: "conditions provide information about the state of the + DNS on the cluster. \n These are the supported DNS conditions: \n + \ * Available - True if the following conditions are met: * + DNS controller daemonset is available. - False if any of those + conditions are unsatisfied." + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_80_csi_snapshot_controller_operator_01_crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_80_csi_snapshot_controller_operator_01_crd.yaml index d8cd7528bdc4..16e04f4c792e 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_80_csi_snapshot_controller_operator_01_crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_80_csi_snapshot_controller_operator_01_crd.yaml @@ -1,142 +1,145 @@ -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: csisnapshotcontrollers.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: operator.openshift.io names: kind: CSISnapshotController plural: csisnapshotcontrollers singular: csisnapshotcontroller - preserveUnknownFields: false scope: Cluster - subresources: - status: {} - version: v1 versions: - name: v1 served: true storage: true - validation: - openAPIV3Schema: - description: CSISnapshotController provides a means to configure an operator - to manage the CSI snapshots. `cluster` is the canonical name. - type: object - required: - - spec - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: spec holds user settable values for configuration - type: object - properties: - logLevel: - description: logLevel is an intent based logging for an overall component. It - does not give fine grained control, but it is a simple way to manage - coarse grained logging choices that operators have to interpret for - their operands. - type: string - managementState: - description: managementState indicates whether and how the operator - should manage the component - type: string - pattern: ^(Managed|Unmanaged|Force|Removed)$ - observedConfig: - description: observedConfig holds a sparse config that controller has - observed from the cluster state. It exists in spec because it is - an input to the level for the operator - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - operatorLogLevel: - description: operatorLogLevel is an intent based logging for the operator - itself. It does not give fine grained control, but it is a simple - way to manage coarse grained logging choices that operators have to - interpret for themselves. - type: string - unsupportedConfigOverrides: - description: 'unsupportedConfigOverrides holds a sparse config that - will override any previously set options. It only needs to be the - fields to override it will end up overlaying in the following order: - 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' - type: object - nullable: true - x-kubernetes-preserve-unknown-fields: true - status: - description: status holds observed values from the cluster. They may not - be overridden. - type: object - properties: - conditions: - description: conditions is a list of conditions and their status - type: array - items: - description: OperatorCondition is just the standard condition fields. + subresources: + status: {} + schema: + openAPIV3Schema: + description: CSISnapshotController provides a means to configure an operator + to manage the CSI snapshots. `cluster` is the canonical name. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + type: object + properties: + logLevel: + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + default: Normal + managementState: + description: managementState indicates whether and how the operator + should manage the component + type: string + pattern: ^(Managed|Unmanaged|Force|Removed)$ + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator type: object - properties: - lastTransitionTime: - type: string - format: date-time - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - generations: - description: generations are used to determine when an item needs to - be reconciled or has changed in a way that needs a reaction. - type: array - items: - description: GenerationStatus keeps track of the generation for a - given resource so that decisions about forced updates can be made. + nullable: true + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' type: object - properties: - group: - description: group is the group of the thing you're tracking - type: string - hash: - description: hash is an optional field set for resources without - generation that are content sensitive like secrets and configmaps - type: string - lastGeneration: - description: lastGeneration is the last generation of the workload - controller involved - type: integer - format: int64 - name: - description: name is the name of the thing you're tracking - type: string - namespace: - description: namespace is where the thing you're tracking is - type: string - resource: - description: resource is the resource type of the thing you're - tracking - type: string - observedGeneration: - description: observedGeneration is the last generation change you've - dealt with - type: integer - format: int64 - readyReplicas: - description: readyReplicas indicates how many replicas are ready and - at the desired state - type: integer - format: int32 - version: - description: version is the level this availability applies to - type: string + nullable: true + x-kubernetes-preserve-unknown-fields: true + status: + description: status holds observed values from the cluster. They may not + be overridden. + type: object + properties: + conditions: + description: conditions is a list of conditions and their status + type: array + items: + description: OperatorCondition is just the standard condition fields. + type: object + properties: + lastTransitionTime: + type: string + format: date-time + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + type: array + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + type: object + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + type: integer + format: int64 + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + type: integer + format: int64 + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + type: integer + format: int32 + version: + description: version is the level this availability applies to + type: string diff --git a/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml new file mode 100644 index 000000000000..4b44f35bdcec --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml @@ -0,0 +1,154 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + include.release.openshift.io/self-managed-high-availability: "true" + name: clustercsidrivers.operator.openshift.io +spec: + group: operator.openshift.io + names: + kind: ClusterCSIDriver + plural: clustercsidrivers + singular: clustercsidriver + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ClusterCSIDriver object allows management and configuration of + a CSI driver operator installed by default in OpenShift. Name of the object + must be name of the CSI driver it operates. See CSIDriverName type for list + of allowed values. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + properties: + name: + enum: + - ebs.csi.aws.com + - manila.csi.openstack.org + - csi.ovirt.org + type: string + type: object + spec: + description: spec holds user settable values for configuration + properties: + logLevel: + default: Normal + description: "logLevel is an intent based logging for an overall component. + \ It does not give fine grained control, but it is a simple way + to manage coarse grained logging choices that operators have to + interpret for their operands. \n Valid values are: \"Normal\", \"Debug\", + \"Trace\", \"TraceAll\". Defaults to \"Normal\"." + type: string + managementState: + description: managementState indicates whether and how the operator + should manage the component + pattern: ^(Managed|Unmanaged|Force|Removed)$ + type: string + observedConfig: + description: observedConfig holds a sparse config that controller + has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + description: operatorLogLevel is an intent based logging for the operator + itself. It does not give fine grained control, but it is a simple + way to manage coarse grained logging choices that operators have + to interpret for themselves. + type: string + unsupportedConfigOverrides: + description: 'unsupportedConfigOverrides holds a sparse config that + will override any previously set options. It only needs to be the + fields to override it will end up overlaying in the following order: + 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides' + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + conditions: + description: conditions is a list of conditions and their status + items: + description: OperatorCondition is just the standard condition fields. + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + format: int64 + type: integer + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + type: object + type: array + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + format: int64 + type: integer + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + format: int32 + type: integer + version: + description: version is the level this availability applies to + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml-patch b/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml-patch new file mode 100644 index 000000000000..22f3a1294412 --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml-patch @@ -0,0 +1,9 @@ +- op: add + path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/metadata/properties + value: + name: + type: string + enum: + - ebs.csi.aws.com + - manila.csi.openstack.org + - csi.ovirt.org diff --git a/vendor/github.com/openshift/api/operator/v1/register.go b/vendor/github.com/openshift/api/operator/v1/register.go index 140cb5854d92..71727a824c2f 100644 --- a/vendor/github.com/openshift/api/operator/v1/register.go +++ b/vendor/github.com/openshift/api/operator/v1/register.go @@ -36,6 +36,10 @@ func addKnownTypes(scheme *runtime.Scheme) error { &AuthenticationList{}, &DNS{}, &DNSList{}, + &CloudCredential{}, + &CloudCredentialList{}, + &ClusterCSIDriver{}, + &ClusterCSIDriverList{}, &Console{}, &ConsoleList{}, &CSISnapshotController{}, diff --git a/vendor/github.com/openshift/api/operator/v1/types.go b/vendor/github.com/openshift/api/operator/v1/types.go index faf5a96c165c..ed11b32191e9 100644 --- a/vendor/github.com/openshift/api/operator/v1/types.go +++ b/vendor/github.com/openshift/api/operator/v1/types.go @@ -51,7 +51,11 @@ type OperatorSpec struct { // logLevel is an intent based logging for an overall component. It does not give fine grained control, but it is a // simple way to manage coarse grained logging choices that operators have to interpret for their operands. + // + // Valid values are: "Normal", "Debug", "Trace", "TraceAll". + // Defaults to "Normal". // +optional + // +kubebuilder:default=Normal LogLevel LogLevel `json:"logLevel"` // operatorLogLevel is an intent based logging for the operator itself. It does not give fine grained control, but it is a diff --git a/vendor/github.com/openshift/api/operator/v1/types_cloudcredential.go b/vendor/github.com/openshift/api/operator/v1/types_cloudcredential.go new file mode 100644 index 000000000000..bb17c89ff59d --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/types_cloudcredential.go @@ -0,0 +1,73 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CloudCredential provides a means to configure an operator to manage CredentialsRequests. +type CloudCredential struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +kubebuilder:validation:Required + // +required + Spec CloudCredentialSpec `json:"spec"` + // +optional + Status CloudCredentialStatus `json:"status"` +} + +// CloudCredentialsMode is the specified mode the cloud-credential-operator +// should reconcile CredentialsRequest with +// +kubebuilder:validation:Enum="";Manual;Mint;Passthrough +type CloudCredentialsMode string + +const ( + // CloudCredentialsModeManual tells cloud-credential-operator to not reconcile any CredentialsRequests + // (primarily used for the disconnected VPC use-cases). + CloudCredentialsModeManual CloudCredentialsMode = "Manual" + + // CloudCredentialsModeMint tells cloud-credential-operator to reconcile all CredentialsRequests + // by minting new users/credentials. + CloudCredentialsModeMint CloudCredentialsMode = "Mint" + + // CloudCredentialsModePassthrough tells cloud-credential-operator to reconcile all CredentialsRequests + // by copying the cloud-specific secret data. + CloudCredentialsModePassthrough CloudCredentialsMode = "Passthrough" + + // CloudCredentialsModeDefault puts CCO into the default mode of operation (per-cloud/platform defaults): + // AWS/Azure/GCP: dynamically determine cluster's cloud credential capabilities to affect + // processing of CredentialsRequests + // All other clouds/platforms (OpenStack, oVirt, vSphere, etc): run in "passthrough" mode + CloudCredentialsModeDefault CloudCredentialsMode = "" +) + +// CloudCredentialSpec is the specification of the desired behavior of the cloud-credential-operator. +type CloudCredentialSpec struct { + OperatorSpec `json:",inline"` + // CredentialsMode allows informing CCO that it should not attempt to dynamically + // determine the root cloud credentials capabilities, and it should just run in + // the specified mode. + // It also allows putting the operator into "manual" mode if desired. + // Leaving the field in default mode runs CCO so that the cluster's cloud credentials + // will be dynamically probed for capabilities (on supported clouds/platforms). + // +optional + CredentialsMode CloudCredentialsMode `json:"credentialsMode,omitempty"` +} + +// CloudCredentialStatus defines the observed status of the cloud-credential-operator. +type CloudCredentialStatus struct { + OperatorStatus `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type CloudCredentialList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []CloudCredential `json:"items"` +} diff --git a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go new file mode 100644 index 000000000000..e6217ab8c067 --- /dev/null +++ b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go @@ -0,0 +1,66 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ClusterCSIDriver is used to manage and configure CSI driver installed by default +// in OpenShift. An example configuration may look like: +// apiVersion: operator.openshift.io/v1 +// kind: "ClusterCSIDriver" +// metadata: +// name: "ebs.csi.aws.com" +// spec: +// logLevel: Debug + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterCSIDriver object allows management and configuration of a CSI driver operator +// installed by default in OpenShift. Name of the object must be name of the CSI driver +// it operates. See CSIDriverName type for list of allowed values. +type ClusterCSIDriver struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // spec holds user settable values for configuration + // +kubebuilder:validation:Required + // +required + Spec ClusterCSIDriverSpec `json:"spec"` + + // status holds observed values from the cluster. They may not be overridden. + // +optional + Status ClusterCSIDriverStatus `json:"status"` +} + +// CSIDriverName is the name of the CSI driver +type CSIDriverName string + +// If you are adding a new driver name here, ensure that kubebuilder:validation:Enum is updated above +// and 0000_90_cluster_csi_driver_01_config.crd.yaml-merge-patch file is also updated with new driver name. +const ( + AWSEBSCSIDriver CSIDriverName = "ebs.csi.aws.com" + ManilaCSIDriver CSIDriverName = "manila.csi.openstack.org" + OvirtCSIDriver CSIDriverName = "csi.ovirt.org" +) + +// ClusterCSIDriverSpec is the desired behavior of CSI driver operator +type ClusterCSIDriverSpec struct { + OperatorSpec `json:",inline"` +} + +// ClusterCSIDriverStatus is the observed status of CSI driver operator +type ClusterCSIDriverStatus struct { + OperatorStatus `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true + +// ClusterCSIDriverList contains a list of ClusterCSIDriver +type ClusterCSIDriverList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterCSIDriver `json:"items"` +} diff --git a/vendor/github.com/openshift/api/operator/v1/types_ingress.go b/vendor/github.com/openshift/api/operator/v1/types_ingress.go index b4938252e37b..4b7bb2fb49d0 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_ingress.go +++ b/vendor/github.com/openshift/api/operator/v1/types_ingress.go @@ -99,6 +99,13 @@ type IngressControllerSpec struct { // the generated certificate's CA will be automatically integrated with the // cluster's trust store. // + // If a wildcard certificate is used and shared by multiple + // HTTP/2 enabled routes (which implies ALPN) then clients + // (i.e., notably browsers) are at liberty to reuse open + // connections. This means a client can reuse a connection to + // another route and that is likely to fail. This behaviour is + // generally known as connection coalescing. + // // The in-use certificate (whether generated or user-specified) will be // automatically integrated with OpenShift's built-in OAuth server. // @@ -278,9 +285,19 @@ type ProviderLoadBalancerParameters struct { // load balancer. Allowed values are "AWS", "Azure", "BareMetal", "GCP", // "OpenStack", and "VSphere". // -// +kubebuilder:validation:Enum=AWS;Azure;BareMetal;GCP;OpenStack;VSphere +// +kubebuilder:validation:Enum=AWS;Azure;BareMetal;GCP;OpenStack;VSphere;IBM type LoadBalancerProviderType string +const ( + AWSLoadBalancerProvider LoadBalancerProviderType = "AWS" + AzureLoadBalancerProvider LoadBalancerProviderType = "Azure" + GCPLoadBalancerProvider LoadBalancerProviderType = "GCP" + OpenStackLoadBalancerProvider LoadBalancerProviderType = "OpenStack" + VSphereLoadBalancerProvider LoadBalancerProviderType = "VSphere" + IBMLoadBalancerProvider LoadBalancerProviderType = "IBM" + BareMetalLoadBalancerProvider LoadBalancerProviderType = "BareMetal" +) + // AWSLoadBalancerParameters provides configuration settings that are // specific to AWS load balancers. // +union @@ -585,6 +602,112 @@ type LoggingDestination struct { Container *ContainerLoggingDestinationParameters `json:"container,omitempty"` } +// IngressControllerCaptureHTTPHeader describes an HTTP header that should be +// captured. +type IngressControllerCaptureHTTPHeader struct { + // name specifies a header name. Its value must be a valid HTTP header + // name as defined in RFC 2616 section 4.2. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern="^[-!#$%&'*+.0-9A-Z^_`a-z|~]+$" + // +required + Name string `json:"name"` + + // maxLength specifies a maximum length for the header value. If a + // header value exceeds this length, the value will be truncated in the + // log message. Note that the ingress controller may impose a separate + // bound on the total length of HTTP headers in a request. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum=1 + // +required + MaxLength int `json:"maxLength"` +} + +// IngressControllerCaptureHTTPHeaders specifies which HTTP headers the +// IngressController captures. +type IngressControllerCaptureHTTPHeaders struct { + // request specifies which HTTP request headers to capture. + // + // If this field is empty, no request headers are captured. + // + // +nullable + // +optional + Request []IngressControllerCaptureHTTPHeader `json:"request,omitempty"` + + // response specifies which HTTP response headers to capture. + // + // If this field is empty, no response headers are captured. + // + // +nullable + // +optional + Response []IngressControllerCaptureHTTPHeader `json:"response,omitempty"` +} + +// CookieMatchType indicates the type of matching used against cookie names to +// select a cookie for capture. +// +kubebuilder:validation:Enum=Exact;Prefix +type CookieMatchType string + +const ( + // CookieMatchTypeExact indicates that an exact string match should be + // performed. + CookieMatchTypeExact CookieMatchType = "Exact" + // CookieMatchTypePrefix indicates that a string prefix match should be + // performed. + CookieMatchTypePrefix CookieMatchType = "Prefix" +) + +// IngressControllerCaptureHTTPCookie describes an HTTP cookie that should be +// captured. +// +union +type IngressControllerCaptureHTTPCookie struct { + // matchType specifies the type of match to be performed on the cookie + // name. Allowed values are "Exact" for an exact string match and + // "Prefix" for a string prefix match. If "Exact" is specified, a name + // must be specified in the name field. If "Prefix" is provided, a + // prefix must be specified in the namePrefix field. For example, + // specifying matchType "Prefix" and namePrefix "foo" will capture a + // cookie named "foo" or "foobar" but not one named "bar". The first + // matching cookie is captured. + // + // +unionDiscriminator + // +kubebuilder:validation:Required + // +required + MatchType CookieMatchType `json:"matchType,omitempty"` + + // name specifies a cookie name. Its value must be a valid HTTP cookie + // name as defined in RFC 6265 section 4.1. + // + // +kubebuilder:validation:Pattern="^[-!#$%&'*+.0-9A-Z^_`a-z|~]*$" + // +kubebuilder:validation:MinLength=0 + // +kubebuilder:validation:MaxLength=1024 + // +optional + Name string `json:"name"` + + // namePrefix specifies a cookie name prefix. Its value must be a valid + // HTTP cookie name as defined in RFC 6265 section 4.1. + // + // +kubebuilder:validation:Pattern="^[-!#$%&'*+.0-9A-Z^_`a-z|~]*$" + // +kubebuilder:validation:MinLength=0 + // +kubebuilder:validation:MaxLength=1024 + // +optional + NamePrefix string `json:"namePrefix"` + + // maxLength specifies a maximum length of the string that will be + // logged, which includes the cookie name, cookie value, and + // one-character delimiter. If the log entry exceeds this length, the + // value will be truncated in the log message. Note that the ingress + // controller may impose a separate bound on the total length of HTTP + // headers in a request. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=1024 + // +required + MaxLength int `json:"maxLength"` +} + // AccessLogging describes how client requests should be logged. type AccessLogging struct { // destination is where access logs go. @@ -601,8 +724,34 @@ type AccessLogging struct { // HAProxy documentation: // http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3 // + // Note that this format only applies to cleartext HTTP connections + // and to secure HTTP connections for which the ingress controller + // terminates encryption (that is, edge-terminated or reencrypt + // connections). It does not affect the log format for TLS passthrough + // connections. + // // +optional HttpLogFormat string `json:"httpLogFormat,omitempty"` + + // httpCaptureHeaders defines HTTP headers that should be captured in + // access logs. If this field is empty, no headers are captured. + // + // Note that this option only applies to cleartext HTTP connections + // and to secure HTTP connections for which the ingress controller + // terminates encryption (that is, edge-terminated or reencrypt + // connections). Headers cannot be captured for TLS passthrough + // connections. + // + // +optional + HTTPCaptureHeaders IngressControllerCaptureHTTPHeaders `json:"httpCaptureHeaders,omitempty"` + + // httpCaptureCookies specifies HTTP cookies that should be captured in + // access logs. If this field is empty, no cookies are captured. + // + // +nullable + // +optional + // +kubebuilder:validation:MaxItems=1 + HTTPCaptureCookies []IngressControllerCaptureHTTPCookie `json:"httpCaptureCookies,omitempty"` } // IngressControllerLogging describes what should be logged where. @@ -632,6 +781,35 @@ const ( NeverHTTPHeaderPolicy IngressControllerHTTPHeaderPolicy = "Never" ) +// IngressControllerHTTPUniqueIdHeaderPolicy describes configuration for a +// unique id header. +type IngressControllerHTTPUniqueIdHeaderPolicy struct { + // name specifies the name of the HTTP header (for example, "unique-id") + // that the ingress controller should inject into HTTP requests. The + // field's value must be a valid HTTP header name as defined in RFC 2616 + // section 4.2. If the field is empty, no header is injected. + // + // +optional + // +kubebuilder:validation:Pattern="^$|^[-!#$%&'*+.0-9A-Z^_`a-z|~]+$" + // +kubebuilder:validation:MinLength=0 + // +kubebuilder:validation:MaxLength=1024 + Name string `json:"name,omitempty"` + + // format specifies the format for the injected HTTP header's value. + // This field has no effect unless name is specified. For the + // HAProxy-based ingress controller implementation, this format uses the + // same syntax as the HTTP log format. If the field is empty, the + // default value is "%{+X}o\\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid"; see the + // corresponding HAProxy documentation: + // http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3 + // + // +optional + // +kubebuilder:validation:Pattern="^(%(%|(\\{[-+]?[QXE](,[-+]?[QXE])*\\})?([A-Za-z]+|\\[[.0-9A-Z_a-z]+(\\([^)]+\\))?(,[.0-9A-Z_a-z]+(\\([^)]+\\))?)*\\]))|[^%[:cntrl:]])*$" + // +kubebuilder:validation:MinLength=0 + // +kubebuilder:validation:MaxLength=1024 + Format string `json:"format,omitempty"` +} + // IngressControllerHTTPHeaders specifies how the IngressController handles // certain HTTP headers. type IngressControllerHTTPHeaders struct { @@ -656,6 +834,18 @@ type IngressControllerHTTPHeaders struct { // // +optional ForwardedHeaderPolicy IngressControllerHTTPHeaderPolicy `json:"forwardedHeaderPolicy,omitempty"` + + // uniqueId describes configuration for a custom HTTP header that the + // ingress controller should inject into incoming HTTP requests. + // Typically, this header is configured to have a value that is unique + // to the HTTP request. The header can be used by applications or + // included in access logs to facilitate tracing individual HTTP + // requests. + // + // If this field is empty, no such header is injected into requests. + // + // +optional + UniqueId IngressControllerHTTPUniqueIdHeaderPolicy `json:"uniqueId,omitempty"` } var ( diff --git a/vendor/github.com/openshift/api/operator/v1/types_network.go b/vendor/github.com/openshift/api/operator/v1/types_network.go index 834fb2b704ab..7e678d11ae09 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_network.go +++ b/vendor/github.com/openshift/api/operator/v1/types_network.go @@ -79,12 +79,14 @@ type NetworkSpec struct { } // ClusterNetworkEntry is a subnet from which to allocate PodIPs. A network of size -// HostPrefix (in CIDR notation) will be allocated when nodes join the cluster. +// HostPrefix (in CIDR notation) will be allocated when nodes join the cluster. If +// the HostPrefix field is not used by the plugin, it can be left unset. // Not all network providers support multiple ClusterNetworks type ClusterNetworkEntry struct { CIDR string `json:"cidr"` // +kubebuilder:validation:Minimum=0 - HostPrefix uint32 `json:"hostPrefix"` + // +optional + HostPrefix uint32 `json:"hostPrefix,omitempty"` } // DefaultNetworkDefinition represents a single network plugin's configuration. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go index f05daeea051f..4fbc10cf23da 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go @@ -73,6 +73,12 @@ func (in *AWSNetworkLoadBalancerParameters) DeepCopy() *AWSNetworkLoadBalancerPa func (in *AccessLogging) DeepCopyInto(out *AccessLogging) { *out = *in in.Destination.DeepCopyInto(&out.Destination) + in.HTTPCaptureHeaders.DeepCopyInto(&out.HTTPCaptureHeaders) + if in.HTTPCaptureCookies != nil { + in, out := &in.HTTPCaptureCookies, &out.HTTPCaptureCookies + *out = make([]IngressControllerCaptureHTTPCookie, len(*in)) + copy(*out, *in) + } return } @@ -298,6 +304,196 @@ func (in *CSISnapshotControllerStatus) DeepCopy() *CSISnapshotControllerStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudCredential) DeepCopyInto(out *CloudCredential) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudCredential. +func (in *CloudCredential) DeepCopy() *CloudCredential { + if in == nil { + return nil + } + out := new(CloudCredential) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CloudCredential) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudCredentialList) DeepCopyInto(out *CloudCredentialList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CloudCredential, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudCredentialList. +func (in *CloudCredentialList) DeepCopy() *CloudCredentialList { + if in == nil { + return nil + } + out := new(CloudCredentialList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CloudCredentialList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudCredentialSpec) DeepCopyInto(out *CloudCredentialSpec) { + *out = *in + in.OperatorSpec.DeepCopyInto(&out.OperatorSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudCredentialSpec. +func (in *CloudCredentialSpec) DeepCopy() *CloudCredentialSpec { + if in == nil { + return nil + } + out := new(CloudCredentialSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudCredentialStatus) DeepCopyInto(out *CloudCredentialStatus) { + *out = *in + in.OperatorStatus.DeepCopyInto(&out.OperatorStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudCredentialStatus. +func (in *CloudCredentialStatus) DeepCopy() *CloudCredentialStatus { + if in == nil { + return nil + } + out := new(CloudCredentialStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCSIDriver) DeepCopyInto(out *ClusterCSIDriver) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCSIDriver. +func (in *ClusterCSIDriver) DeepCopy() *ClusterCSIDriver { + if in == nil { + return nil + } + out := new(ClusterCSIDriver) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCSIDriver) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCSIDriverList) DeepCopyInto(out *ClusterCSIDriverList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterCSIDriver, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCSIDriverList. +func (in *ClusterCSIDriverList) DeepCopy() *ClusterCSIDriverList { + if in == nil { + return nil + } + out := new(ClusterCSIDriverList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCSIDriverList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCSIDriverSpec) DeepCopyInto(out *ClusterCSIDriverSpec) { + *out = *in + in.OperatorSpec.DeepCopyInto(&out.OperatorSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCSIDriverSpec. +func (in *ClusterCSIDriverSpec) DeepCopy() *ClusterCSIDriverSpec { + if in == nil { + return nil + } + out := new(ClusterCSIDriverSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCSIDriverStatus) DeepCopyInto(out *ClusterCSIDriverStatus) { + *out = *in + in.OperatorStatus.DeepCopyInto(&out.OperatorStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCSIDriverStatus. +func (in *ClusterCSIDriverStatus) DeepCopy() *ClusterCSIDriverStatus { + if in == nil { + return nil + } + out := new(ClusterCSIDriverStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterNetworkEntry) DeepCopyInto(out *ClusterNetworkEntry) { *out = *in @@ -975,9 +1171,68 @@ func (in *IngressController) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressControllerCaptureHTTPCookie) DeepCopyInto(out *IngressControllerCaptureHTTPCookie) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressControllerCaptureHTTPCookie. +func (in *IngressControllerCaptureHTTPCookie) DeepCopy() *IngressControllerCaptureHTTPCookie { + if in == nil { + return nil + } + out := new(IngressControllerCaptureHTTPCookie) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressControllerCaptureHTTPHeader) DeepCopyInto(out *IngressControllerCaptureHTTPHeader) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressControllerCaptureHTTPHeader. +func (in *IngressControllerCaptureHTTPHeader) DeepCopy() *IngressControllerCaptureHTTPHeader { + if in == nil { + return nil + } + out := new(IngressControllerCaptureHTTPHeader) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressControllerCaptureHTTPHeaders) DeepCopyInto(out *IngressControllerCaptureHTTPHeaders) { + *out = *in + if in.Request != nil { + in, out := &in.Request, &out.Request + *out = make([]IngressControllerCaptureHTTPHeader, len(*in)) + copy(*out, *in) + } + if in.Response != nil { + in, out := &in.Response, &out.Response + *out = make([]IngressControllerCaptureHTTPHeader, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressControllerCaptureHTTPHeaders. +func (in *IngressControllerCaptureHTTPHeaders) DeepCopy() *IngressControllerCaptureHTTPHeaders { + if in == nil { + return nil + } + out := new(IngressControllerCaptureHTTPHeaders) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressControllerHTTPHeaders) DeepCopyInto(out *IngressControllerHTTPHeaders) { *out = *in + out.UniqueId = in.UniqueId return } @@ -991,6 +1246,22 @@ func (in *IngressControllerHTTPHeaders) DeepCopy() *IngressControllerHTTPHeaders return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressControllerHTTPUniqueIdHeaderPolicy) DeepCopyInto(out *IngressControllerHTTPUniqueIdHeaderPolicy) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressControllerHTTPUniqueIdHeaderPolicy. +func (in *IngressControllerHTTPUniqueIdHeaderPolicy) DeepCopy() *IngressControllerHTTPUniqueIdHeaderPolicy { + if in == nil { + return nil + } + out := new(IngressControllerHTTPUniqueIdHeaderPolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressControllerList) DeepCopyInto(out *IngressControllerList) { *out = *in diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go index 144e714e0cd5..f4cef5edd3ad 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go @@ -57,7 +57,7 @@ func (OperatorCondition) SwaggerDoc() map[string]string { var map_OperatorSpec = map[string]string{ "": "OperatorSpec contains common fields operators need. It is intended to be anonymous included inside of the Spec struct for your particular operator.", "managementState": "managementState indicates whether and how the operator should manage the component", - "logLevel": "logLevel is an intent based logging for an overall component. It does not give fine grained control, but it is a simple way to manage coarse grained logging choices that operators have to interpret for their operands.", + "logLevel": "logLevel is an intent based logging for an overall component. It does not give fine grained control, but it is a simple way to manage coarse grained logging choices that operators have to interpret for their operands.\n\nValid values are: \"Normal\", \"Debug\", \"Trace\", \"TraceAll\". Defaults to \"Normal\".", "operatorLogLevel": "operatorLogLevel is an intent based logging for the operator itself. It does not give fine grained control, but it is a simple way to manage coarse grained logging choices that operators have to interpret for themselves.", "unsupportedConfigOverrides": "unsupportedConfigOverrides holds a sparse config that will override any previously set options. It only needs to be the fields to override it will end up overlaying in the following order: 1. hardcoded defaults 2. observedConfig 3. unsupportedConfigOverrides", "observedConfig": "observedConfig holds a sparse config that controller has observed from the cluster state. It exists in spec because it is an input to the level for the operator", @@ -134,6 +134,31 @@ func (OAuthAPIServerStatus) SwaggerDoc() map[string]string { return map_OAuthAPIServerStatus } +var map_CloudCredential = map[string]string{ + "": "CloudCredential provides a means to configure an operator to manage CredentialsRequests.", +} + +func (CloudCredential) SwaggerDoc() map[string]string { + return map_CloudCredential +} + +var map_CloudCredentialSpec = map[string]string{ + "": "CloudCredentialSpec is the specification of the desired behavior of the cloud-credential-operator.", + "credentialsMode": "CredentialsMode allows informing CCO that it should not attempt to dynamically determine the root cloud credentials capabilities, and it should just run in the specified mode. It also allows putting the operator into \"manual\" mode if desired. Leaving the field in default mode runs CCO so that the cluster's cloud credentials will be dynamically probed for capabilities (on supported clouds/platforms).", +} + +func (CloudCredentialSpec) SwaggerDoc() map[string]string { + return map_CloudCredentialSpec +} + +var map_CloudCredentialStatus = map[string]string{ + "": "CloudCredentialStatus defines the observed status of the cloud-credential-operator.", +} + +func (CloudCredentialStatus) SwaggerDoc() map[string]string { + return map_CloudCredentialStatus +} + var map_Config = map[string]string{ "": "Config provides information to configure the config operator.", "spec": "spec is the specification of the desired behavior of the Config Operator.", @@ -220,6 +245,40 @@ func (StatuspageProvider) SwaggerDoc() map[string]string { return map_StatuspageProvider } +var map_ClusterCSIDriver = map[string]string{ + "": "ClusterCSIDriver object allows management and configuration of a CSI driver operator installed by default in OpenShift. Name of the object must be name of the CSI driver it operates. See CSIDriverName type for list of allowed values.", + "spec": "spec holds user settable values for configuration", + "status": "status holds observed values from the cluster. They may not be overridden.", +} + +func (ClusterCSIDriver) SwaggerDoc() map[string]string { + return map_ClusterCSIDriver +} + +var map_ClusterCSIDriverList = map[string]string{ + "": "ClusterCSIDriverList contains a list of ClusterCSIDriver", +} + +func (ClusterCSIDriverList) SwaggerDoc() map[string]string { + return map_ClusterCSIDriverList +} + +var map_ClusterCSIDriverSpec = map[string]string{ + "": "ClusterCSIDriverSpec is the desired behavior of CSI driver operator", +} + +func (ClusterCSIDriverSpec) SwaggerDoc() map[string]string { + return map_ClusterCSIDriverSpec +} + +var map_ClusterCSIDriverStatus = map[string]string{ + "": "ClusterCSIDriverStatus is the observed status of CSI driver operator", +} + +func (ClusterCSIDriverStatus) SwaggerDoc() map[string]string { + return map_ClusterCSIDriverStatus +} + var map_CSISnapshotController = map[string]string{ "": "CSISnapshotController provides a means to configure an operator to manage the CSI snapshots. `cluster` is the canonical name.", "spec": "spec holds user settable values for configuration", @@ -357,9 +416,11 @@ func (AWSNetworkLoadBalancerParameters) SwaggerDoc() map[string]string { } var map_AccessLogging = map[string]string{ - "": "AccessLogging describes how client requests should be logged.", - "destination": "destination is where access logs go.", - "httpLogFormat": "httpLogFormat specifies the format of the log message for an HTTP request.\n\nIf this field is empty, log messages use the implementation's default HTTP log format. For HAProxy's default HTTP log format, see the HAProxy documentation: http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3", + "": "AccessLogging describes how client requests should be logged.", + "destination": "destination is where access logs go.", + "httpLogFormat": "httpLogFormat specifies the format of the log message for an HTTP request.\n\nIf this field is empty, log messages use the implementation's default HTTP log format. For HAProxy's default HTTP log format, see the HAProxy documentation: http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3\n\nNote that this format only applies to cleartext HTTP connections and to secure HTTP connections for which the ingress controller terminates encryption (that is, edge-terminated or reencrypt connections). It does not affect the log format for TLS passthrough connections.", + "httpCaptureHeaders": "httpCaptureHeaders defines HTTP headers that should be captured in access logs. If this field is empty, no headers are captured.\n\nNote that this option only applies to cleartext HTTP connections and to secure HTTP connections for which the ingress controller terminates encryption (that is, edge-terminated or reencrypt connections). Headers cannot be captured for TLS passthrough connections.", + "httpCaptureCookies": "httpCaptureCookies specifies HTTP cookies that should be captured in access logs. If this field is empty, no cookies are captured.", } func (AccessLogging) SwaggerDoc() map[string]string { @@ -405,15 +466,58 @@ func (IngressController) SwaggerDoc() map[string]string { return map_IngressController } +var map_IngressControllerCaptureHTTPCookie = map[string]string{ + "": "IngressControllerCaptureHTTPCookie describes an HTTP cookie that should be captured.", + "matchType": "matchType specifies the type of match to be performed on the cookie name. Allowed values are \"Exact\" for an exact string match and \"Prefix\" for a string prefix match. If \"Exact\" is specified, a name must be specified in the name field. If \"Prefix\" is provided, a prefix must be specified in the namePrefix field. For example, specifying matchType \"Prefix\" and namePrefix \"foo\" will capture a cookie named \"foo\" or \"foobar\" but not one named \"bar\". The first matching cookie is captured.", + "name": "name specifies a cookie name. Its value must be a valid HTTP cookie name as defined in RFC 6265 section 4.1.", + "namePrefix": "namePrefix specifies a cookie name prefix. Its value must be a valid HTTP cookie name as defined in RFC 6265 section 4.1.", + "maxLength": "maxLength specifies a maximum length of the string that will be logged, which includes the cookie name, cookie value, and one-character delimiter. If the log entry exceeds this length, the value will be truncated in the log message. Note that the ingress controller may impose a separate bound on the total length of HTTP headers in a request.", +} + +func (IngressControllerCaptureHTTPCookie) SwaggerDoc() map[string]string { + return map_IngressControllerCaptureHTTPCookie +} + +var map_IngressControllerCaptureHTTPHeader = map[string]string{ + "": "IngressControllerCaptureHTTPHeader describes an HTTP header that should be captured.", + "name": "name specifies a header name. Its value must be a valid HTTP header name as defined in RFC 2616 section 4.2.", + "maxLength": "maxLength specifies a maximum length for the header value. If a header value exceeds this length, the value will be truncated in the log message. Note that the ingress controller may impose a separate bound on the total length of HTTP headers in a request.", +} + +func (IngressControllerCaptureHTTPHeader) SwaggerDoc() map[string]string { + return map_IngressControllerCaptureHTTPHeader +} + +var map_IngressControllerCaptureHTTPHeaders = map[string]string{ + "": "IngressControllerCaptureHTTPHeaders specifies which HTTP headers the IngressController captures.", + "request": "request specifies which HTTP request headers to capture.\n\nIf this field is empty, no request headers are captured.", + "response": "response specifies which HTTP response headers to capture.\n\nIf this field is empty, no response headers are captured.", +} + +func (IngressControllerCaptureHTTPHeaders) SwaggerDoc() map[string]string { + return map_IngressControllerCaptureHTTPHeaders +} + var map_IngressControllerHTTPHeaders = map[string]string{ "": "IngressControllerHTTPHeaders specifies how the IngressController handles certain HTTP headers.", "forwardedHeaderPolicy": "forwardedHeaderPolicy specifies when and how the IngressController sets the Forwarded, X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, and X-Forwarded-Proto-Version HTTP headers. The value may be one of the following:\n\n* \"Append\", which specifies that the IngressController appends the\n headers, preserving existing headers.\n\n* \"Replace\", which specifies that the IngressController sets the\n headers, replacing any existing Forwarded or X-Forwarded-* headers.\n\n* \"IfNone\", which specifies that the IngressController sets the\n headers if they are not already set.\n\n* \"Never\", which specifies that the IngressController never sets the\n headers, preserving any existing headers.\n\nBy default, the policy is \"Append\".", + "uniqueId": "uniqueId describes configuration for a custom HTTP header that the ingress controller should inject into incoming HTTP requests. Typically, this header is configured to have a value that is unique to the HTTP request. The header can be used by applications or included in access logs to facilitate tracing individual HTTP requests.\n\nIf this field is empty, no such header is injected into requests.", } func (IngressControllerHTTPHeaders) SwaggerDoc() map[string]string { return map_IngressControllerHTTPHeaders } +var map_IngressControllerHTTPUniqueIdHeaderPolicy = map[string]string{ + "": "IngressControllerHTTPUniqueIdHeaderPolicy describes configuration for a unique id header.", + "name": "name specifies the name of the HTTP header (for example, \"unique-id\") that the ingress controller should inject into HTTP requests. The field's value must be a valid HTTP header name as defined in RFC 2616 section 4.2. If the field is empty, no header is injected.", + "format": "format specifies the format for the injected HTTP header's value. This field has no effect unless name is specified. For the HAProxy-based ingress controller implementation, this format uses the same syntax as the HTTP log format. If the field is empty, the default value is \"%{+X}o\\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid\"; see the corresponding HAProxy documentation: http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3", +} + +func (IngressControllerHTTPUniqueIdHeaderPolicy) SwaggerDoc() map[string]string { + return map_IngressControllerHTTPUniqueIdHeaderPolicy +} + var map_IngressControllerList = map[string]string{ "": "IngressControllerList contains a list of IngressControllers.", } @@ -436,7 +540,7 @@ var map_IngressControllerSpec = map[string]string{ "domain": "domain is a DNS name serviced by the ingress controller and is used to configure multiple features:\n\n* For the LoadBalancerService endpoint publishing strategy, domain is\n used to configure DNS records. See endpointPublishingStrategy.\n\n* When using a generated default certificate, the certificate will be valid\n for domain and its subdomains. See defaultCertificate.\n\n* The value is published to individual Route statuses so that end-users\n know where to target external DNS records.\n\ndomain must be unique among all IngressControllers, and cannot be updated.\n\nIf empty, defaults to ingress.config.openshift.io/cluster .spec.domain.", "replicas": "replicas is the desired number of ingress controller replicas. If unset, defaults to 2.", "endpointPublishingStrategy": "endpointPublishingStrategy is used to publish the ingress controller endpoints to other networks, enable load balancer integrations, etc.\n\nIf unset, the default is based on infrastructure.config.openshift.io/cluster .status.platform:\n\n AWS: LoadBalancerService (with External scope)\n Azure: LoadBalancerService (with External scope)\n GCP: LoadBalancerService (with External scope)\n IBMCloud: LoadBalancerService (with External scope)\n Libvirt: HostNetwork\n\nAny other platform types (including None) default to HostNetwork.\n\nendpointPublishingStrategy cannot be updated.", - "defaultCertificate": "defaultCertificate is a reference to a secret containing the default certificate served by the ingress controller. When Routes don't specify their own certificate, defaultCertificate is used.\n\nThe secret must contain the following keys and data:\n\n tls.crt: certificate file contents\n tls.key: key file contents\n\nIf unset, a wildcard certificate is automatically generated and used. The certificate is valid for the ingress controller domain (and subdomains) and the generated certificate's CA will be automatically integrated with the cluster's trust store.\n\nThe in-use certificate (whether generated or user-specified) will be automatically integrated with OpenShift's built-in OAuth server.", + "defaultCertificate": "defaultCertificate is a reference to a secret containing the default certificate served by the ingress controller. When Routes don't specify their own certificate, defaultCertificate is used.\n\nThe secret must contain the following keys and data:\n\n tls.crt: certificate file contents\n tls.key: key file contents\n\nIf unset, a wildcard certificate is automatically generated and used. The certificate is valid for the ingress controller domain (and subdomains) and the generated certificate's CA will be automatically integrated with the cluster's trust store.\n\nIf a wildcard certificate is used and shared by multiple HTTP/2 enabled routes (which implies ALPN) then clients (i.e., notably browsers) are at liberty to reuse open connections. This means a client can reuse a connection to another route and that is likely to fail. This behaviour is generally known as connection coalescing.\n\nThe in-use certificate (whether generated or user-specified) will be automatically integrated with OpenShift's built-in OAuth server.", "namespaceSelector": "namespaceSelector is used to filter the set of namespaces serviced by the ingress controller. This is useful for implementing shards.\n\nIf unset, the default is no filtering.", "routeSelector": "routeSelector is used to filter the set of Routes serviced by the ingress controller. This is useful for implementing shards.\n\nIf unset, the default is no filtering.", "nodePlacement": "nodePlacement enables explicit control over the scheduling of the ingress controller.\n\nIf unset, defaults are used. See NodePlacement for more details.", @@ -612,7 +716,7 @@ func (AdditionalNetworkDefinition) SwaggerDoc() map[string]string { } var map_ClusterNetworkEntry = map[string]string{ - "": "ClusterNetworkEntry is a subnet from which to allocate PodIPs. A network of size HostPrefix (in CIDR notation) will be allocated when nodes join the cluster. Not all network providers support multiple ClusterNetworks", + "": "ClusterNetworkEntry is a subnet from which to allocate PodIPs. A network of size HostPrefix (in CIDR notation) will be allocated when nodes join the cluster. If the HostPrefix field is not used by the plugin, it can be left unset. Not all network providers support multiple ClusterNetworks", } func (ClusterNetworkEntry) SwaggerDoc() map[string]string { diff --git a/vendor/github.com/openshift/api/operator/v1alpha1/0000_10_config-operator_01_imagecontentsourcepolicy.crd.yaml b/vendor/github.com/openshift/api/operator/v1alpha1/0000_10_config-operator_01_imagecontentsourcepolicy.crd.yaml index b28b0415c9a5..66cb5c6a3eac 100644 --- a/vendor/github.com/openshift/api/operator/v1alpha1/0000_10_config-operator_01_imagecontentsourcepolicy.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1alpha1/0000_10_config-operator_01_imagecontentsourcepolicy.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: imagecontentsourcepolicies.operator.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: operator.openshift.io scope: Cluster diff --git a/vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/0000_10-pod-network-connectivity-check.crd.yaml b/vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/0000_10-pod-network-connectivity-check.crd.yaml index ddd34c42e169..5cc8e56f907f 100644 --- a/vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/0000_10-pod-network-connectivity-check.crd.yaml +++ b/vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/0000_10-pod-network-connectivity-check.crd.yaml @@ -1,6 +1,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: + annotations: + include.release.openshift.io/self-managed-high-availability: "true" creationTimestamp: null name: podnetworkconnectivitychecks.controlplane.operator.openshift.io spec: diff --git a/vendor/github.com/openshift/api/quota/v1/0000_03_quota-openshift_01_clusterresourcequota.crd.yaml b/vendor/github.com/openshift/api/quota/v1/0000_03_quota-openshift_01_clusterresourcequota.crd.yaml index 8c425675c889..8382490414d4 100644 --- a/vendor/github.com/openshift/api/quota/v1/0000_03_quota-openshift_01_clusterresourcequota.crd.yaml +++ b/vendor/github.com/openshift/api/quota/v1/0000_03_quota-openshift_01_clusterresourcequota.crd.yaml @@ -1,6 +1,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: + annotations: + include.release.openshift.io/self-managed-high-availability: "true" name: clusterresourcequotas.quota.openshift.io spec: group: quota.openshift.io @@ -39,6 +41,10 @@ spec: properties: hard: additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ type: "" x-kubernetes-int-or-string: true description: 'hard is the set of desired hard limits for each named @@ -174,13 +180,21 @@ spec: properties: hard: additionalProperties: - type: string + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true description: 'Hard is the set of enforced hard limits for each named resource. More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/' type: object used: additionalProperties: - type: string + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true description: Used is the current observed total usage of the resource in the namespace. type: object @@ -197,13 +211,21 @@ spec: properties: hard: additionalProperties: - type: string + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true description: 'Hard is the set of enforced hard limits for each named resource. More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/' type: object used: additionalProperties: - type: string + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true description: Used is the current observed total usage of the resource in the namespace. type: object diff --git a/vendor/github.com/openshift/api/route/v1/generated.proto b/vendor/github.com/openshift/api/route/v1/generated.proto index 24476e1a3c85..c4bc446e34f3 100644 --- a/vendor/github.com/openshift/api/route/v1/generated.proto +++ b/vendor/github.com/openshift/api/route/v1/generated.proto @@ -30,6 +30,14 @@ option go_package = "v1"; // return information to clients about the names and states of the route under each router. // If a client chooses a duplicate name, for instance, the route status conditions are used // to indicate the route cannot be chosen. +// +// To enable HTTP/2 ALPN on a route it requires a custom +// (non-wildcard) certificate. This prevents connection coalescing by +// clients, notably web browsers. We do not support HTTP/2 ALPN on +// routes that use the default certificate because of the risk of +// connection re-use/coalescing. Routes that do not have their own +// custom certificate will not be HTTP/2 ALPN-enabled on either the +// frontend or the backend. message Route { optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; diff --git a/vendor/github.com/openshift/api/route/v1/types.go b/vendor/github.com/openshift/api/route/v1/types.go index 6c9d80b98a5d..9e59c6978278 100644 --- a/vendor/github.com/openshift/api/route/v1/types.go +++ b/vendor/github.com/openshift/api/route/v1/types.go @@ -26,6 +26,14 @@ import ( // return information to clients about the names and states of the route under each router. // If a client chooses a duplicate name, for instance, the route status conditions are used // to indicate the route cannot be chosen. +// +// To enable HTTP/2 ALPN on a route it requires a custom +// (non-wildcard) certificate. This prevents connection coalescing by +// clients, notably web browsers. We do not support HTTP/2 ALPN on +// routes that use the default certificate because of the risk of +// connection re-use/coalescing. Routes that do not have their own +// custom certificate will not be HTTP/2 ALPN-enabled on either the +// frontend or the backend. type Route struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` diff --git a/vendor/github.com/openshift/api/route/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/route/v1/zz_generated.swagger_doc_generated.go index c0fc24b6530c..9974795f6272 100644 --- a/vendor/github.com/openshift/api/route/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/route/v1/zz_generated.swagger_doc_generated.go @@ -12,7 +12,7 @@ package v1 // AUTO-GENERATED FUNCTIONS START HERE var map_Route = map[string]string{ - "": "A route allows developers to expose services through an HTTP(S) aware load balancing and proxy layer via a public DNS entry. The route may further specify TLS options and a certificate, or specify a public CNAME that the router should also accept for HTTP and HTTPS traffic. An administrator typically configures their router to be visible outside the cluster firewall, and may also add additional security, caching, or traffic controls on the service content. Routers usually talk directly to the service endpoints.\n\nOnce a route is created, the `host` field may not be changed. Generally, routers use the oldest route with a given host when resolving conflicts.\n\nRouters are subject to additional customization and may support additional controls via the annotations field.\n\nBecause administrators may configure multiple routers, the route status field is used to return information to clients about the names and states of the route under each router. If a client chooses a duplicate name, for instance, the route status conditions are used to indicate the route cannot be chosen.", + "": "A route allows developers to expose services through an HTTP(S) aware load balancing and proxy layer via a public DNS entry. The route may further specify TLS options and a certificate, or specify a public CNAME that the router should also accept for HTTP and HTTPS traffic. An administrator typically configures their router to be visible outside the cluster firewall, and may also add additional security, caching, or traffic controls on the service content. Routers usually talk directly to the service endpoints.\n\nOnce a route is created, the `host` field may not be changed. Generally, routers use the oldest route with a given host when resolving conflicts.\n\nRouters are subject to additional customization and may support additional controls via the annotations field.\n\nBecause administrators may configure multiple routers, the route status field is used to return information to clients about the names and states of the route under each router. If a client chooses a duplicate name, for instance, the route status conditions are used to indicate the route cannot be chosen.\n\nTo enable HTTP/2 ALPN on a route it requires a custom (non-wildcard) certificate. This prevents connection coalescing by clients, notably web browsers. We do not support HTTP/2 ALPN on routes that use the default certificate because of the risk of connection re-use/coalescing. Routes that do not have their own custom certificate will not be HTTP/2 ALPN-enabled on either the frontend or the backend.", "spec": "spec is the desired state of the route", "status": "status is the current state of the route", } diff --git a/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml b/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml index 80d451c64770..e8f10ce7d876 100644 --- a/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml +++ b/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml @@ -2,6 +2,8 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: securitycontextconstraints.security.openshift.io + annotations: + include.release.openshift.io/self-managed-high-availability: "true" spec: group: security.openshift.io names: diff --git a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/capabilities/mustrunas.go b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/capabilities/mustrunas.go index 3fd4eb9b04cc..9e6e1d5a59b5 100644 --- a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/capabilities/mustrunas.go +++ b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/capabilities/mustrunas.go @@ -67,7 +67,7 @@ func (s *defaultCapabilities) Generate(pod *api.Pod, container *api.Container) ( } // Validate ensures that the specified values fall within the range of the strategy. -func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container, capabilities *api.Capabilities) field.ErrorList { +func (s *defaultCapabilities) Validate(fldPath *field.Path, pod *api.Pod, container *api.Container, capabilities *api.Capabilities) field.ErrorList { allErrs := field.ErrorList{} if capabilities == nil { @@ -80,7 +80,7 @@ func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container, c // container has no requested caps but we have required caps. We should have something in // at least the drops on the container. - allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities"), capabilities, + allErrs = append(allErrs, field.Invalid(fldPath.Child("capabilities"), capabilities, "required capabilities are not set on the securityContext")) return allErrs } @@ -98,7 +98,7 @@ func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container, c for _, cap := range capabilities.Add { sCap := string(cap) if !defaultAdd.Has(sCap) && !allowedAdd.Has(sCap) { - allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities", "add"), sCap, "capability may not be added")) + allErrs = append(allErrs, field.Invalid(fldPath.Child("capabilities", "add"), sCap, "capability may not be added")) } } @@ -108,7 +108,7 @@ func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container, c for _, requiredDrop := range s.requiredDropCapabilities { sDrop := string(requiredDrop) if !containerDrops.Has(sDrop) { - allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities", "drop"), capabilities.Drop, + allErrs = append(allErrs, field.Invalid(fldPath.Child("capabilities", "drop"), capabilities.Drop, fmt.Sprintf("%s is required to be dropped but was not found", sDrop))) } } diff --git a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/capabilities/types.go b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/capabilities/types.go index b92c1c817cb1..2c030d3947bb 100644 --- a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/capabilities/types.go +++ b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/capabilities/types.go @@ -10,5 +10,5 @@ type CapabilitiesSecurityContextConstraintsStrategy interface { // Generate creates the capabilities based on policy rules. Generate(pod *api.Pod, container *api.Container) (*api.Capabilities, error) // Validate ensures that the specified values fall within the range of the strategy. - Validate(pod *api.Pod, container *api.Container, capabilities *api.Capabilities) field.ErrorList + Validate(fldPath *field.Path, pod *api.Pod, container *api.Container, capabilities *api.Capabilities) field.ErrorList } diff --git a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/mustrunas.go b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/mustrunas.go index f821e4e90450..14d3f06ee3b0 100644 --- a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/mustrunas.go +++ b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/mustrunas.go @@ -45,17 +45,17 @@ func (s *mustRunAs) GenerateSingle(_ *api.Pod) (*int64, error) { // Validate ensures that the specified values fall within the range of the strategy. // Groups are passed in here to allow this strategy to support multiple group fields (fsgroup and // supplemental groups). -func (s *mustRunAs) Validate(_ *api.Pod, groups []int64) field.ErrorList { +func (s *mustRunAs) Validate(fldPath *field.Path, _ *api.Pod, groups []int64) field.ErrorList { allErrs := field.ErrorList{} if len(groups) == 0 && len(s.ranges) > 0 { - allErrs = append(allErrs, field.Invalid(field.NewPath(s.field), groups, "unable to validate empty groups against required ranges")) + allErrs = append(allErrs, field.Invalid(fldPath.Child(s.field), groups, "unable to validate empty groups against required ranges")) } for _, group := range groups { if !s.isGroupValid(group) { detail := fmt.Sprintf("%d is not an allowed group", group) - allErrs = append(allErrs, field.Invalid(field.NewPath(s.field), groups, detail)) + allErrs = append(allErrs, field.Invalid(fldPath.Child(s.field), groups, detail)) } } diff --git a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/runasany.go b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/runasany.go index 850e802bd98c..01b300e4c0f6 100644 --- a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/runasany.go +++ b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/runasany.go @@ -27,7 +27,7 @@ func (s *runAsAny) GenerateSingle(_ *api.Pod) (*int64, error) { } // Validate ensures that the specified values fall within the range of the strategy. -func (s *runAsAny) Validate(_ *api.Pod, groups []int64) field.ErrorList { +func (s *runAsAny) Validate(fldPath *field.Path, _ *api.Pod, groups []int64) field.ErrorList { return field.ErrorList{} } diff --git a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/types.go b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/types.go index ca7c3419015e..752195ab957f 100644 --- a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/types.go +++ b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/group/types.go @@ -15,5 +15,5 @@ type GroupSecurityContextConstraintsStrategy interface { // value to return if configured with multiple ranges. This is used for FSGroup. GenerateSingle(pod *api.Pod) (*int64, error) // Validate ensures that the specified values fall within the range of the strategy. - Validate(pod *api.Pod, groups []int64) field.ErrorList + Validate(fldPath *field.Path, pod *api.Pod, groups []int64) field.ErrorList } diff --git a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/sccmatching/provider.go b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/sccmatching/provider.go index 5e67237669db..5428d375dae7 100644 --- a/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/sccmatching/provider.go +++ b/vendor/github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/sccmatching/provider.go @@ -215,8 +215,8 @@ func (s *simpleProvider) ValidatePodSecurityContext(pod *api.Pod, fldPath *field if fsGroup := sc.FSGroup(); fsGroup != nil { fsGroups = append(fsGroups, *fsGroup) } - allErrs = append(allErrs, s.fsGroupStrategy.Validate(pod, fsGroups)...) - allErrs = append(allErrs, s.supplementalGroupStrategy.Validate(pod, sc.SupplementalGroups())...) + allErrs = append(allErrs, s.fsGroupStrategy.Validate(fldPath, pod, fsGroups)...) + allErrs = append(allErrs, s.supplementalGroupStrategy.Validate(fldPath, pod, sc.SupplementalGroups())...) allErrs = append(allErrs, s.seccompStrategy.ValidatePod(pod)...) allErrs = append(allErrs, s.seLinuxStrategy.Validate(fldPath.Child("seLinuxOptions"), pod, nil, sc.SELinuxOptions())...) @@ -284,7 +284,7 @@ func (s *simpleProvider) ValidateContainerSecurityContext(pod *api.Pod, containe podSC := securitycontext.NewPodSecurityContextAccessor(pod.Spec.SecurityContext) sc := securitycontext.NewEffectiveContainerSecurityContextAccessor(podSC, securitycontext.NewContainerSecurityContextMutator(container.SecurityContext)) - allErrs = append(allErrs, s.runAsUserStrategy.Validate(fldPath.Child("securityContext"), pod, container, sc.RunAsNonRoot(), sc.RunAsUser())...) + allErrs = append(allErrs, s.runAsUserStrategy.Validate(fldPath, pod, container, sc.RunAsNonRoot(), sc.RunAsUser())...) allErrs = append(allErrs, s.seLinuxStrategy.Validate(fldPath.Child("seLinuxOptions"), pod, container, sc.SELinuxOptions())...) allErrs = append(allErrs, s.seccompStrategy.ValidateContainer(pod, container)...) @@ -293,7 +293,7 @@ func (s *simpleProvider) ValidateContainerSecurityContext(pod *api.Pod, containe allErrs = append(allErrs, field.Invalid(fldPath.Child("privileged"), *privileged, "Privileged containers are not allowed")) } - allErrs = append(allErrs, s.capabilitiesStrategy.Validate(pod, container, sc.Capabilities())...) + allErrs = append(allErrs, s.capabilitiesStrategy.Validate(fldPath, pod, container, sc.Capabilities())...) if !s.scc.AllowHostNetwork && podSC.HostNetwork() { allErrs = append(allErrs, field.Invalid(fldPath.Child("hostNetwork"), podSC.HostNetwork(), "Host network is not allowed to be used")) diff --git a/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk b/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk index 857ddc9b57bd..3841aff135fb 100644 --- a/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk +++ b/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk @@ -17,7 +17,7 @@ GOFMT_FLAGS ?=-s -l GOLINT ?=golint go_version :=$(shell $(GO) version | sed -E -e 's/.*go([0-9]+.[0-9]+.[0-9]+).*/\1/') -GO_REQUIRED_MIN_VERSION ?=1.13.4 +GO_REQUIRED_MIN_VERSION ?=1.14.4 ifneq "$(GO_REQUIRED_MIN_VERSION)" "" $(call require_minimal_version,$(GO),GO_REQUIRED_MIN_VERSION,$(go_version)) endif diff --git a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/controller-gen.mk b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/controller-gen.mk index eeb29d7d356d..c8dc0ac46e02 100644 --- a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/controller-gen.mk +++ b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/controller-gen.mk @@ -1,6 +1,6 @@ self_dir :=$(dir $(lastword $(MAKEFILE_LIST))) -CONTROLLER_GEN_VERSION ?=v0.2.1-37-ga3cca5d +CONTROLLER_GEN_VERSION ?=v0.2.5 CONTROLLER_GEN ?=$(PERMANENT_TMP_GOPATH)/bin/controller-gen controller_gen_dir :=$(dir $(CONTROLLER_GEN)) diff --git a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/crd-schema-gen.mk b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/crd-schema-gen.mk index ce8d22f72dd4..3a24a57e1587 100644 --- a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/crd-schema-gen.mk +++ b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/crd-schema-gen.mk @@ -2,11 +2,19 @@ self_dir :=$(dir $(lastword $(MAKEFILE_LIST))) # $1 - crd file # $2 - patch file -define patch-crd +define patch-crd-yq $(YQ) m -i -x '$(1)' '$(2)' endef +# $1 - crd file +# $2 - patch file +define patch-crd-yaml-patch + $(YAML_PATCH) -o '$(2)' < '$(1)' > '$(1).patched' + mv '$(1).patched' '$(1)' + +endef + empty := define diff-file @@ -22,7 +30,8 @@ define run-crd-gen schemapatch:manifests="$(2)" \ paths="$(subst $(empty) ,;,$(1))" \ output:dir="$(3)" - $$(foreach p,$$(wildcard $(2)/*.crd.yaml-merge-patch),$$(call patch-crd,$$(subst $(2),$(3),$$(basename $$(p))).yaml,$$(p))) + $$(foreach p,$$(wildcard $(2)/*.crd.yaml-merge-patch),$$(call patch-crd-yq,$$(subst $(2),$(3),$$(basename $$(p))).yaml,$$(p))) + $$(foreach p,$$(wildcard $(2)/*.crd.yaml-patch),$$(call patch-crd-yaml-patch,$$(subst $(2),$(3),$$(basename $$(p))).yaml,$$(p))) endef @@ -32,7 +41,7 @@ endef # $4 - output define add-crd-gen-internal -update-codegen-crds-$(1): ensure-controller-gen ensure-yq +update-codegen-crds-$(1): ensure-controller-gen ensure-yq ensure-yaml-patch $(call run-crd-gen,$(2),$(3),$(4)) .PHONY: update-codegen-crds-$(1) @@ -40,7 +49,7 @@ update-codegen-crds: update-codegen-crds-$(1) .PHONY: update-codegen-crds verify-codegen-crds-$(1): VERIFY_CODEGEN_CRD_TMP_DIR:=$$(shell mktemp -d) -verify-codegen-crds-$(1): ensure-controller-gen ensure-yq +verify-codegen-crds-$(1): ensure-controller-gen ensure-yq ensure-yaml-patch $(call run-crd-gen,$(2),$(3),$$(VERIFY_CODEGEN_CRD_TMP_DIR)) $$(foreach p,$$(wildcard $(3)/*crd.yaml),$$(call diff-file,$$(p),$$(subst $(3),$$(VERIFY_CODEGEN_CRD_TMP_DIR),$$(p)))) .PHONY: verify-codegen-crds-$(1) @@ -77,4 +86,5 @@ include $(addprefix $(self_dir), \ ../../lib/tmp.mk \ ../../targets/openshift/controller-gen.mk \ ../../targets/openshift/yq.mk \ + ../../targets/openshift/yaml-patch.mk \ ) diff --git a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/yaml-patch.mk b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/yaml-patch.mk new file mode 100644 index 000000000000..d6569e609727 --- /dev/null +++ b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/yaml-patch.mk @@ -0,0 +1,32 @@ +self_dir :=$(dir $(lastword $(MAKEFILE_LIST))) + +YAML_PATCH ?=$(PERMANENT_TMP_GOPATH)/bin/yaml-patch +yaml_patch_dir :=$(dir $(YAML_PATCH)) + + +ensure-yaml-patch: +ifeq "" "$(wildcard $(YAML_PATCH))" + $(info Installing yaml-patch into '$(YAML_PATCH)') + mkdir -p '$(yaml_patch_dir)' + curl -s -f -L https://github.com/krishicks/yaml-patch/releases/download/v0.0.10/yaml_patch_$(GOHOSTOS) -o '$(YAML_PATCH)' + chmod +x '$(YAML_PATCH)'; +else + $(info Using existing yaml-patch from "$(YAML_PATCH)") +endif +.PHONY: ensure-yaml-patch + +clean-yaml-patch: + $(RM) '$(YAML_PATCH)' + if [ -d '$(yaml_patch_dir)' ]; then rmdir --ignore-fail-on-non-empty -p '$(yaml_patch_dir)'; fi +.PHONY: clean-yaml-patch + +clean: clean-yaml-patch + + +# We need to be careful to expand all the paths before any include is done +# or self_dir could be modified for the next include by the included file. +# Also doing this at the end of the file allows us to use self_dir before it could be modified. +include $(addprefix $(self_dir), \ + ../../lib/golang.mk \ + ../../lib/tmp.mk \ +) diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/apiserver.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/apiserver.go index 63bb7ecfdc40..247e40017ba2 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/apiserver.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/apiserver.go @@ -10,10 +10,13 @@ import ( ) // APIServerLister helps list APIServers. +// All objects returned here must be treated as read-only. type APIServerLister interface { // List lists all APIServers in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.APIServer, err error) // Get retrieves the APIServer from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.APIServer, error) APIServerListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/authentication.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/authentication.go index 27c113a90219..99cc82485171 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/authentication.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/authentication.go @@ -10,10 +10,13 @@ import ( ) // AuthenticationLister helps list Authentications. +// All objects returned here must be treated as read-only. type AuthenticationLister interface { // List lists all Authentications in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Authentication, err error) // Get retrieves the Authentication from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Authentication, error) AuthenticationListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/build.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/build.go index e8fa1c564f66..77a1a36ff887 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/build.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/build.go @@ -10,10 +10,13 @@ import ( ) // BuildLister helps list Builds. +// All objects returned here must be treated as read-only. type BuildLister interface { // List lists all Builds in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Build, err error) // Get retrieves the Build from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Build, error) BuildListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/clusteroperator.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/clusteroperator.go index bb88edee61eb..e4c95773a055 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/clusteroperator.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/clusteroperator.go @@ -10,10 +10,13 @@ import ( ) // ClusterOperatorLister helps list ClusterOperators. +// All objects returned here must be treated as read-only. type ClusterOperatorLister interface { // List lists all ClusterOperators in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.ClusterOperator, err error) // Get retrieves the ClusterOperator from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.ClusterOperator, error) ClusterOperatorListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/clusterversion.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/clusterversion.go index c053383a16c4..ab309a1b2070 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/clusterversion.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/clusterversion.go @@ -10,10 +10,13 @@ import ( ) // ClusterVersionLister helps list ClusterVersions. +// All objects returned here must be treated as read-only. type ClusterVersionLister interface { // List lists all ClusterVersions in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.ClusterVersion, err error) // Get retrieves the ClusterVersion from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.ClusterVersion, error) ClusterVersionListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/console.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/console.go index 8a17d3e2b02d..daaf7aa92f19 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/console.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/console.go @@ -10,10 +10,13 @@ import ( ) // ConsoleLister helps list Consoles. +// All objects returned here must be treated as read-only. type ConsoleLister interface { // List lists all Consoles in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Console, err error) // Get retrieves the Console from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Console, error) ConsoleListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/dns.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/dns.go index 84ee5477064a..89441b3a9d5e 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/dns.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/dns.go @@ -10,10 +10,13 @@ import ( ) // DNSLister helps list DNSes. +// All objects returned here must be treated as read-only. type DNSLister interface { // List lists all DNSes in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.DNS, err error) // Get retrieves the DNS from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.DNS, error) DNSListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/featuregate.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/featuregate.go index cb2b6cf16324..4c796e80ff25 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/featuregate.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/featuregate.go @@ -10,10 +10,13 @@ import ( ) // FeatureGateLister helps list FeatureGates. +// All objects returned here must be treated as read-only. type FeatureGateLister interface { // List lists all FeatureGates in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.FeatureGate, err error) // Get retrieves the FeatureGate from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.FeatureGate, error) FeatureGateListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/image.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/image.go index 0696e718a648..f563f919a4ef 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/image.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/image.go @@ -10,10 +10,13 @@ import ( ) // ImageLister helps list Images. +// All objects returned here must be treated as read-only. type ImageLister interface { // List lists all Images in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Image, err error) // Get retrieves the Image from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Image, error) ImageListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/infrastructure.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/infrastructure.go index 90e4e54a964f..33f4b229e2c0 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/infrastructure.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/infrastructure.go @@ -10,10 +10,13 @@ import ( ) // InfrastructureLister helps list Infrastructures. +// All objects returned here must be treated as read-only. type InfrastructureLister interface { // List lists all Infrastructures in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Infrastructure, err error) // Get retrieves the Infrastructure from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Infrastructure, error) InfrastructureListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/ingress.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/ingress.go index 7fff5b055497..78b0fd1254a7 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/ingress.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/ingress.go @@ -10,10 +10,13 @@ import ( ) // IngressLister helps list Ingresses. +// All objects returned here must be treated as read-only. type IngressLister interface { // List lists all Ingresses in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Ingress, err error) // Get retrieves the Ingress from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Ingress, error) IngressListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/network.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/network.go index 18c2fa73d7c1..174fdb45b767 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/network.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/network.go @@ -10,10 +10,13 @@ import ( ) // NetworkLister helps list Networks. +// All objects returned here must be treated as read-only. type NetworkLister interface { // List lists all Networks in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Network, err error) // Get retrieves the Network from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Network, error) NetworkListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/oauth.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/oauth.go index b09ca24b318a..8d9882471b30 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/oauth.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/oauth.go @@ -10,10 +10,13 @@ import ( ) // OAuthLister helps list OAuths. +// All objects returned here must be treated as read-only. type OAuthLister interface { // List lists all OAuths in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.OAuth, err error) // Get retrieves the OAuth from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.OAuth, error) OAuthListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/operatorhub.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/operatorhub.go index 21acaf91e142..b69a49471c0f 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/operatorhub.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/operatorhub.go @@ -10,10 +10,13 @@ import ( ) // OperatorHubLister helps list OperatorHubs. +// All objects returned here must be treated as read-only. type OperatorHubLister interface { // List lists all OperatorHubs in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.OperatorHub, err error) // Get retrieves the OperatorHub from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.OperatorHub, error) OperatorHubListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/project.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/project.go index 18c7fbd08def..30273ba6bec7 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/project.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/project.go @@ -10,10 +10,13 @@ import ( ) // ProjectLister helps list Projects. +// All objects returned here must be treated as read-only. type ProjectLister interface { // List lists all Projects in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Project, err error) // Get retrieves the Project from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Project, error) ProjectListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/proxy.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/proxy.go index 032f5d125df7..8ecb633c3e96 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/proxy.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/proxy.go @@ -10,10 +10,13 @@ import ( ) // ProxyLister helps list Proxies. +// All objects returned here must be treated as read-only. type ProxyLister interface { // List lists all Proxies in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Proxy, err error) // Get retrieves the Proxy from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Proxy, error) ProxyListerExpansion } diff --git a/vendor/github.com/openshift/client-go/config/listers/config/v1/scheduler.go b/vendor/github.com/openshift/client-go/config/listers/config/v1/scheduler.go index 7074a8b71aab..3e2f81ea4425 100644 --- a/vendor/github.com/openshift/client-go/config/listers/config/v1/scheduler.go +++ b/vendor/github.com/openshift/client-go/config/listers/config/v1/scheduler.go @@ -10,10 +10,13 @@ import ( ) // SchedulerLister helps list Schedulers. +// All objects returned here must be treated as read-only. type SchedulerLister interface { // List lists all Schedulers in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Scheduler, err error) // Get retrieves the Scheduler from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Scheduler, error) SchedulerListerExpansion } diff --git a/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthaccesstoken.go b/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthaccesstoken.go index 33b815c2d79b..8486f9181981 100644 --- a/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthaccesstoken.go +++ b/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthaccesstoken.go @@ -10,10 +10,13 @@ import ( ) // OAuthAccessTokenLister helps list OAuthAccessTokens. +// All objects returned here must be treated as read-only. type OAuthAccessTokenLister interface { // List lists all OAuthAccessTokens in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.OAuthAccessToken, err error) // Get retrieves the OAuthAccessToken from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.OAuthAccessToken, error) OAuthAccessTokenListerExpansion } diff --git a/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthauthorizetoken.go b/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthauthorizetoken.go index 5481a4819fbe..d42a247b5275 100644 --- a/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthauthorizetoken.go +++ b/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthauthorizetoken.go @@ -10,10 +10,13 @@ import ( ) // OAuthAuthorizeTokenLister helps list OAuthAuthorizeTokens. +// All objects returned here must be treated as read-only. type OAuthAuthorizeTokenLister interface { // List lists all OAuthAuthorizeTokens in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.OAuthAuthorizeToken, err error) // Get retrieves the OAuthAuthorizeToken from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.OAuthAuthorizeToken, error) OAuthAuthorizeTokenListerExpansion } diff --git a/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthclient.go b/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthclient.go index 79e6f3483a41..51c1b62a9f37 100644 --- a/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthclient.go +++ b/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthclient.go @@ -10,10 +10,13 @@ import ( ) // OAuthClientLister helps list OAuthClients. +// All objects returned here must be treated as read-only. type OAuthClientLister interface { // List lists all OAuthClients in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.OAuthClient, err error) // Get retrieves the OAuthClient from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.OAuthClient, error) OAuthClientListerExpansion } diff --git a/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthclientauthorization.go b/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthclientauthorization.go index 73131ed4c0d6..2627a03e219e 100644 --- a/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthclientauthorization.go +++ b/vendor/github.com/openshift/client-go/oauth/listers/oauth/v1/oauthclientauthorization.go @@ -10,10 +10,13 @@ import ( ) // OAuthClientAuthorizationLister helps list OAuthClientAuthorizations. +// All objects returned here must be treated as read-only. type OAuthClientAuthorizationLister interface { // List lists all OAuthClientAuthorizations in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.OAuthClientAuthorization, err error) // Get retrieves the OAuthClientAuthorization from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.OAuthClientAuthorization, error) OAuthClientAuthorizationListerExpansion } diff --git a/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/cloudcredential.go b/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/cloudcredential.go new file mode 100644 index 000000000000..f501305cedc4 --- /dev/null +++ b/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/cloudcredential.go @@ -0,0 +1,168 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/openshift/api/operator/v1" + scheme "github.com/openshift/client-go/operator/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CloudCredentialsGetter has a method to return a CloudCredentialInterface. +// A group's client should implement this interface. +type CloudCredentialsGetter interface { + CloudCredentials() CloudCredentialInterface +} + +// CloudCredentialInterface has methods to work with CloudCredential resources. +type CloudCredentialInterface interface { + Create(ctx context.Context, cloudCredential *v1.CloudCredential, opts metav1.CreateOptions) (*v1.CloudCredential, error) + Update(ctx context.Context, cloudCredential *v1.CloudCredential, opts metav1.UpdateOptions) (*v1.CloudCredential, error) + UpdateStatus(ctx context.Context, cloudCredential *v1.CloudCredential, opts metav1.UpdateOptions) (*v1.CloudCredential, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CloudCredential, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CloudCredentialList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CloudCredential, err error) + CloudCredentialExpansion +} + +// cloudCredentials implements CloudCredentialInterface +type cloudCredentials struct { + client rest.Interface +} + +// newCloudCredentials returns a CloudCredentials +func newCloudCredentials(c *OperatorV1Client) *cloudCredentials { + return &cloudCredentials{ + client: c.RESTClient(), + } +} + +// Get takes name of the cloudCredential, and returns the corresponding cloudCredential object, and an error if there is any. +func (c *cloudCredentials) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CloudCredential, err error) { + result = &v1.CloudCredential{} + err = c.client.Get(). + Resource("cloudcredentials"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CloudCredentials that match those selectors. +func (c *cloudCredentials) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CloudCredentialList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CloudCredentialList{} + err = c.client.Get(). + Resource("cloudcredentials"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cloudCredentials. +func (c *cloudCredentials) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("cloudcredentials"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cloudCredential and creates it. Returns the server's representation of the cloudCredential, and an error, if there is any. +func (c *cloudCredentials) Create(ctx context.Context, cloudCredential *v1.CloudCredential, opts metav1.CreateOptions) (result *v1.CloudCredential, err error) { + result = &v1.CloudCredential{} + err = c.client.Post(). + Resource("cloudcredentials"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cloudCredential). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cloudCredential and updates it. Returns the server's representation of the cloudCredential, and an error, if there is any. +func (c *cloudCredentials) Update(ctx context.Context, cloudCredential *v1.CloudCredential, opts metav1.UpdateOptions) (result *v1.CloudCredential, err error) { + result = &v1.CloudCredential{} + err = c.client.Put(). + Resource("cloudcredentials"). + Name(cloudCredential.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cloudCredential). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *cloudCredentials) UpdateStatus(ctx context.Context, cloudCredential *v1.CloudCredential, opts metav1.UpdateOptions) (result *v1.CloudCredential, err error) { + result = &v1.CloudCredential{} + err = c.client.Put(). + Resource("cloudcredentials"). + Name(cloudCredential.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cloudCredential). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cloudCredential and deletes it. Returns an error if one occurs. +func (c *cloudCredentials) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("cloudcredentials"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cloudCredentials) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("cloudcredentials"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cloudCredential. +func (c *cloudCredentials) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CloudCredential, err error) { + result = &v1.CloudCredential{} + err = c.client.Patch(pt). + Resource("cloudcredentials"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/clustercsidriver.go b/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/clustercsidriver.go new file mode 100644 index 000000000000..26827b95511a --- /dev/null +++ b/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/clustercsidriver.go @@ -0,0 +1,168 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/openshift/api/operator/v1" + scheme "github.com/openshift/client-go/operator/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ClusterCSIDriversGetter has a method to return a ClusterCSIDriverInterface. +// A group's client should implement this interface. +type ClusterCSIDriversGetter interface { + ClusterCSIDrivers() ClusterCSIDriverInterface +} + +// ClusterCSIDriverInterface has methods to work with ClusterCSIDriver resources. +type ClusterCSIDriverInterface interface { + Create(ctx context.Context, clusterCSIDriver *v1.ClusterCSIDriver, opts metav1.CreateOptions) (*v1.ClusterCSIDriver, error) + Update(ctx context.Context, clusterCSIDriver *v1.ClusterCSIDriver, opts metav1.UpdateOptions) (*v1.ClusterCSIDriver, error) + UpdateStatus(ctx context.Context, clusterCSIDriver *v1.ClusterCSIDriver, opts metav1.UpdateOptions) (*v1.ClusterCSIDriver, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ClusterCSIDriver, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ClusterCSIDriverList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterCSIDriver, err error) + ClusterCSIDriverExpansion +} + +// clusterCSIDrivers implements ClusterCSIDriverInterface +type clusterCSIDrivers struct { + client rest.Interface +} + +// newClusterCSIDrivers returns a ClusterCSIDrivers +func newClusterCSIDrivers(c *OperatorV1Client) *clusterCSIDrivers { + return &clusterCSIDrivers{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterCSIDriver, and returns the corresponding clusterCSIDriver object, and an error if there is any. +func (c *clusterCSIDrivers) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ClusterCSIDriver, err error) { + result = &v1.ClusterCSIDriver{} + err = c.client.Get(). + Resource("clustercsidrivers"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterCSIDrivers that match those selectors. +func (c *clusterCSIDrivers) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterCSIDriverList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ClusterCSIDriverList{} + err = c.client.Get(). + Resource("clustercsidrivers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterCSIDrivers. +func (c *clusterCSIDrivers) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clustercsidrivers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a clusterCSIDriver and creates it. Returns the server's representation of the clusterCSIDriver, and an error, if there is any. +func (c *clusterCSIDrivers) Create(ctx context.Context, clusterCSIDriver *v1.ClusterCSIDriver, opts metav1.CreateOptions) (result *v1.ClusterCSIDriver, err error) { + result = &v1.ClusterCSIDriver{} + err = c.client.Post(). + Resource("clustercsidrivers"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterCSIDriver). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a clusterCSIDriver and updates it. Returns the server's representation of the clusterCSIDriver, and an error, if there is any. +func (c *clusterCSIDrivers) Update(ctx context.Context, clusterCSIDriver *v1.ClusterCSIDriver, opts metav1.UpdateOptions) (result *v1.ClusterCSIDriver, err error) { + result = &v1.ClusterCSIDriver{} + err = c.client.Put(). + Resource("clustercsidrivers"). + Name(clusterCSIDriver.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterCSIDriver). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *clusterCSIDrivers) UpdateStatus(ctx context.Context, clusterCSIDriver *v1.ClusterCSIDriver, opts metav1.UpdateOptions) (result *v1.ClusterCSIDriver, err error) { + result = &v1.ClusterCSIDriver{} + err = c.client.Put(). + Resource("clustercsidrivers"). + Name(clusterCSIDriver.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterCSIDriver). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the clusterCSIDriver and deletes it. Returns an error if one occurs. +func (c *clusterCSIDrivers) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("clustercsidrivers"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterCSIDrivers) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clustercsidrivers"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched clusterCSIDriver. +func (c *clusterCSIDrivers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterCSIDriver, err error) { + result = &v1.ClusterCSIDriver{} + err = c.client.Patch(pt). + Resource("clustercsidrivers"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/generated_expansion.go b/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/generated_expansion.go index a9713c58aaec..b3894c955591 100644 --- a/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/generated_expansion.go +++ b/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/generated_expansion.go @@ -6,6 +6,10 @@ type AuthenticationExpansion interface{} type CSISnapshotControllerExpansion interface{} +type CloudCredentialExpansion interface{} + +type ClusterCSIDriverExpansion interface{} + type ConfigExpansion interface{} type ConsoleExpansion interface{} diff --git a/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/operator_client.go b/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/operator_client.go index 5a4ae0ccbc18..b5e4004d6798 100644 --- a/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/operator_client.go +++ b/vendor/github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1/operator_client.go @@ -12,6 +12,8 @@ type OperatorV1Interface interface { RESTClient() rest.Interface AuthenticationsGetter CSISnapshotControllersGetter + CloudCredentialsGetter + ClusterCSIDriversGetter ConfigsGetter ConsolesGetter DNSesGetter @@ -43,6 +45,14 @@ func (c *OperatorV1Client) CSISnapshotControllers() CSISnapshotControllerInterfa return newCSISnapshotControllers(c) } +func (c *OperatorV1Client) CloudCredentials() CloudCredentialInterface { + return newCloudCredentials(c) +} + +func (c *OperatorV1Client) ClusterCSIDrivers() ClusterCSIDriverInterface { + return newClusterCSIDrivers(c) +} + func (c *OperatorV1Client) Configs() ConfigInterface { return newConfigs(c) } diff --git a/vendor/github.com/openshift/client-go/quota/listers/quota/v1/appliedclusterresourcequota.go b/vendor/github.com/openshift/client-go/quota/listers/quota/v1/appliedclusterresourcequota.go index e5b1c92f452e..1f2e026b5637 100644 --- a/vendor/github.com/openshift/client-go/quota/listers/quota/v1/appliedclusterresourcequota.go +++ b/vendor/github.com/openshift/client-go/quota/listers/quota/v1/appliedclusterresourcequota.go @@ -10,8 +10,10 @@ import ( ) // AppliedClusterResourceQuotaLister helps list AppliedClusterResourceQuotas. +// All objects returned here must be treated as read-only. type AppliedClusterResourceQuotaLister interface { // List lists all AppliedClusterResourceQuotas in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.AppliedClusterResourceQuota, err error) // AppliedClusterResourceQuotas returns an object that can list and get AppliedClusterResourceQuotas. AppliedClusterResourceQuotas(namespace string) AppliedClusterResourceQuotaNamespaceLister @@ -42,10 +44,13 @@ func (s *appliedClusterResourceQuotaLister) AppliedClusterResourceQuotas(namespa } // AppliedClusterResourceQuotaNamespaceLister helps list and get AppliedClusterResourceQuotas. +// All objects returned here must be treated as read-only. type AppliedClusterResourceQuotaNamespaceLister interface { // List lists all AppliedClusterResourceQuotas in the indexer for a given namespace. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.AppliedClusterResourceQuota, err error) // Get retrieves the AppliedClusterResourceQuota from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.AppliedClusterResourceQuota, error) AppliedClusterResourceQuotaNamespaceListerExpansion } diff --git a/vendor/github.com/openshift/client-go/quota/listers/quota/v1/clusterresourcequota.go b/vendor/github.com/openshift/client-go/quota/listers/quota/v1/clusterresourcequota.go index 487da1121730..dffa1f0f7140 100644 --- a/vendor/github.com/openshift/client-go/quota/listers/quota/v1/clusterresourcequota.go +++ b/vendor/github.com/openshift/client-go/quota/listers/quota/v1/clusterresourcequota.go @@ -10,10 +10,13 @@ import ( ) // ClusterResourceQuotaLister helps list ClusterResourceQuotas. +// All objects returned here must be treated as read-only. type ClusterResourceQuotaLister interface { // List lists all ClusterResourceQuotas in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.ClusterResourceQuota, err error) // Get retrieves the ClusterResourceQuota from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.ClusterResourceQuota, error) ClusterResourceQuotaListerExpansion } diff --git a/vendor/github.com/openshift/client-go/security/listers/security/v1/rangeallocation.go b/vendor/github.com/openshift/client-go/security/listers/security/v1/rangeallocation.go index 1f6ffcdc2d3e..c945dbb5b252 100644 --- a/vendor/github.com/openshift/client-go/security/listers/security/v1/rangeallocation.go +++ b/vendor/github.com/openshift/client-go/security/listers/security/v1/rangeallocation.go @@ -10,10 +10,13 @@ import ( ) // RangeAllocationLister helps list RangeAllocations. +// All objects returned here must be treated as read-only. type RangeAllocationLister interface { // List lists all RangeAllocations in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.RangeAllocation, err error) // Get retrieves the RangeAllocation from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.RangeAllocation, error) RangeAllocationListerExpansion } diff --git a/vendor/github.com/openshift/client-go/security/listers/security/v1/securitycontextconstraints.go b/vendor/github.com/openshift/client-go/security/listers/security/v1/securitycontextconstraints.go index b6f3131aba93..6fe0bd1d598c 100644 --- a/vendor/github.com/openshift/client-go/security/listers/security/v1/securitycontextconstraints.go +++ b/vendor/github.com/openshift/client-go/security/listers/security/v1/securitycontextconstraints.go @@ -10,10 +10,13 @@ import ( ) // SecurityContextConstraintsLister helps list SecurityContextConstraints. +// All objects returned here must be treated as read-only. type SecurityContextConstraintsLister interface { // List lists all SecurityContextConstraints in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.SecurityContextConstraints, err error) // Get retrieves the SecurityContextConstraints from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.SecurityContextConstraints, error) SecurityContextConstraintsListerExpansion } diff --git a/vendor/github.com/openshift/client-go/user/listers/user/v1/group.go b/vendor/github.com/openshift/client-go/user/listers/user/v1/group.go index 9951a096c2ba..824b87634e52 100644 --- a/vendor/github.com/openshift/client-go/user/listers/user/v1/group.go +++ b/vendor/github.com/openshift/client-go/user/listers/user/v1/group.go @@ -10,10 +10,13 @@ import ( ) // GroupLister helps list Groups. +// All objects returned here must be treated as read-only. type GroupLister interface { // List lists all Groups in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Group, err error) // Get retrieves the Group from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Group, error) GroupListerExpansion } diff --git a/vendor/github.com/openshift/client-go/user/listers/user/v1/identity.go b/vendor/github.com/openshift/client-go/user/listers/user/v1/identity.go index 851e4e8a9ede..67d3decbeb48 100644 --- a/vendor/github.com/openshift/client-go/user/listers/user/v1/identity.go +++ b/vendor/github.com/openshift/client-go/user/listers/user/v1/identity.go @@ -10,10 +10,13 @@ import ( ) // IdentityLister helps list Identities. +// All objects returned here must be treated as read-only. type IdentityLister interface { // List lists all Identities in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.Identity, err error) // Get retrieves the Identity from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.Identity, error) IdentityListerExpansion } diff --git a/vendor/github.com/openshift/client-go/user/listers/user/v1/user.go b/vendor/github.com/openshift/client-go/user/listers/user/v1/user.go index 45725c117725..45164add31df 100644 --- a/vendor/github.com/openshift/client-go/user/listers/user/v1/user.go +++ b/vendor/github.com/openshift/client-go/user/listers/user/v1/user.go @@ -10,10 +10,13 @@ import ( ) // UserLister helps list Users. +// All objects returned here must be treated as read-only. type UserLister interface { // List lists all Users in the indexer. + // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1.User, err error) // Get retrieves the User from the index for a given name. + // Objects returned here must be treated as read-only. Get(name string) (*v1.User, error) UserListerExpansion } diff --git a/vendor/github.com/openshift/library-go/pkg/controller/factory/base_controller.go b/vendor/github.com/openshift/library-go/pkg/controller/factory/base_controller.go index 95c7855160d8..5a1b1177f917 100644 --- a/vendor/github.com/openshift/library-go/pkg/controller/factory/base_controller.go +++ b/vendor/github.com/openshift/library-go/pkg/controller/factory/base_controller.go @@ -24,6 +24,8 @@ import ( // This can be also done by re-adding the key to queue, but this is cheaper and more convenient. var SyntheticRequeueError = errors.New("synthetic requeue request") +var defaultCacheSyncTimeout = 10 * time.Minute + // baseController represents generic Kubernetes controller boiler-plate type baseController struct { name string @@ -34,6 +36,7 @@ type baseController struct { resyncEvery time.Duration resyncSchedules []cron.Schedule postStartHooks []PostStartHook + cacheSyncTimeout time.Duration } var _ Controller = &baseController{} @@ -62,8 +65,16 @@ func (s *scheduledJob) Run() { func (c *baseController) Run(ctx context.Context, workers int) { // HandleCrash recovers panics defer utilruntime.HandleCrash() - if !cache.WaitForNamedCacheSync(c.name, ctx.Done(), c.cachesToSync...) { - panic("timeout waiting for informer cache") // this will be recovered using HandleCrash() + + // give caches 10 minutes to sync + cacheSyncCtx, cacheSyncCancel := context.WithTimeout(ctx, c.cacheSyncTimeout) + defer cacheSyncCancel() + if !cache.WaitForNamedCacheSync(c.name, cacheSyncCtx.Done(), c.cachesToSync...) { + // the parent context is closed, it means we are shutting down, do not call panic() + if ctx.Err() != nil { + return + } + panic("failed to wait for cache to sync") } var workerWg sync.WaitGroup diff --git a/vendor/github.com/openshift/library-go/pkg/controller/factory/factory.go b/vendor/github.com/openshift/library-go/pkg/controller/factory/factory.go index 0dd16dd66806..61c96b8a58a7 100644 --- a/vendor/github.com/openshift/library-go/pkg/controller/factory/factory.go +++ b/vendor/github.com/openshift/library-go/pkg/controller/factory/factory.go @@ -197,6 +197,8 @@ func (f *Factory) ToController(name string, eventRecorder events.Recorder) Contr resyncSchedules: cronSchedules, cachesToSync: append([]cache.InformerSynced{}, f.cachesToSync...), syncContext: ctx, + postStartHooks: f.postStartHooks, + cacheSyncTimeout: defaultCacheSyncTimeout, } for i := range f.informerQueueKeys { diff --git a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go index 77ef3df04e27..544ea9fb8559 100644 --- a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go +++ b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go @@ -120,28 +120,30 @@ var ciphersTLS13 = map[string]uint16{ } var ciphers = map[string]uint16{ - "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, - "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, - "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, - "TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, - "TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256, - "TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256, - "TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384, - "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - "TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, - "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, + "TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + "TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256, + "TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, } // openSSLToIANACiphersMap maps OpenSSL cipher suite names to IANA names @@ -153,17 +155,17 @@ var openSSLToIANACiphersMap = map[string]string{ // "TLS_CHACHA20_POLY1305_SHA256": "TLS_CHACHA20_POLY1305_SHA256", // 0x13,0x03 // TLS 1.2 - "ECDHE-ECDSA-AES128-GCM-SHA256": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", // 0xC0,0x2B - "ECDHE-RSA-AES128-GCM-SHA256": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", // 0xC0,0x2F - "ECDHE-ECDSA-AES256-GCM-SHA384": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", // 0xC0,0x2C - "ECDHE-RSA-AES256-GCM-SHA384": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", // 0xC0,0x30 - "ECDHE-ECDSA-CHACHA20-POLY1305": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", // 0xCC,0xA9 - "ECDHE-RSA-CHACHA20-POLY1305": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", // 0xCC,0xA8 - "ECDHE-ECDSA-AES128-SHA256": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", // 0xC0,0x23 - "ECDHE-RSA-AES128-SHA256": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", // 0xC0,0x27 - "AES128-GCM-SHA256": "TLS_RSA_WITH_AES_128_GCM_SHA256", // 0x00,0x9C - "AES256-GCM-SHA384": "TLS_RSA_WITH_AES_256_GCM_SHA384", // 0x00,0x9D - "AES128-SHA256": "TLS_RSA_WITH_AES_128_CBC_SHA256", // 0x00,0x3C + "ECDHE-ECDSA-AES128-GCM-SHA256": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", // 0xC0,0x2B + "ECDHE-RSA-AES128-GCM-SHA256": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", // 0xC0,0x2F + "ECDHE-ECDSA-AES256-GCM-SHA384": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", // 0xC0,0x2C + "ECDHE-RSA-AES256-GCM-SHA384": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", // 0xC0,0x30 + "ECDHE-ECDSA-CHACHA20-POLY1305": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", // 0xCC,0xA9 + "ECDHE-RSA-CHACHA20-POLY1305": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", // 0xCC,0xA8 + "ECDHE-ECDSA-AES128-SHA256": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", // 0xC0,0x23 + "ECDHE-RSA-AES128-SHA256": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", // 0xC0,0x27 + "AES128-GCM-SHA256": "TLS_RSA_WITH_AES_128_GCM_SHA256", // 0x00,0x9C + "AES256-GCM-SHA384": "TLS_RSA_WITH_AES_256_GCM_SHA384", // 0x00,0x9D + "AES128-SHA256": "TLS_RSA_WITH_AES_128_CBC_SHA256", // 0x00,0x3C // TLS 1 "ECDHE-ECDSA-AES128-SHA": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", // 0xC0,0x09 @@ -189,6 +191,17 @@ func CipherSuitesToNamesOrDie(intVals []uint16) []string { // CipherSuiteToNameOrDie given a cipher suite as an int, return its readable name func CipherSuiteToNameOrDie(intVal uint16) string { + // The following suite ids appear twice in the cipher map (with + // and without the _SHA256 suffix) for the purposes of backwards + // compatibility. Always return the current rather than the legacy + // name. + switch intVal { + case tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" + case tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" + } + matches := []string{} for key, version := range ciphers { if version == intVal { @@ -247,8 +260,8 @@ func DefaultCiphers() []uint16 { // See RFC7540, section 9.2 (Use of TLS Features) and Appendix A // (TLS 1.2 Cipher Suite Black List). return []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, - tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // required by http/2 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go index ab767695fee6..1246ae863a3b 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go @@ -117,10 +117,37 @@ func WithImpersonation(handler http.Handler, a authorizer.Authorizer, s runtime. } } - if !groupsSpecified && username != user.Anonymous { - // When impersonating a non-anonymous user, if no groups were specified - // include the system:authenticated group in the impersonated user info - groups = append(groups, user.AllAuthenticated) + if username != user.Anonymous { + // When impersonating a non-anonymous user, include the 'system:authenticated' group + // in the impersonated user info: + // - if no groups were specified + // - if a group has been specified other than 'system:authenticated' + // + // If 'system:unauthenticated' group has been specified we should not include + // the 'system:authenticated' group. + addAuthenticated := true + for _, group := range groups { + if group == user.AllAuthenticated || group == user.AllUnauthenticated { + addAuthenticated = false + break + } + } + + if addAuthenticated { + groups = append(groups, user.AllAuthenticated) + } + } else { + addUnauthenticated := true + for _, group := range groups { + if group == user.AllUnauthenticated { + addUnauthenticated = false + break + } + } + + if addUnauthenticated { + groups = append(groups, user.AllUnauthenticated) + } } newUser := &user.DefaultInfo{ diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD index adcc9235dcc5..1a7b9961d4d6 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD @@ -27,8 +27,8 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/merge:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/merge:go_default_library", ], ) @@ -79,9 +79,9 @@ go_test( "//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/merge:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/typed:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/merge:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/typed:go_default_library", "//vendor/sigs.k8s.io/yaml:go_default_library", ], ) diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers.go index 8e926995329d..ae91bf0b9e16 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers.go @@ -23,7 +23,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) type capManagersManager struct { diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go index 77ce75ab29b6..2f6e5bd08c4d 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go @@ -28,8 +28,8 @@ import ( "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/klog/v2" openapiproto "k8s.io/kube-openapi/pkg/util/proto" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/merge" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" ) // DefaultMaxUpdateManagers defines the default maximum retained number of managedFields entries from updates diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/BUILD b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/BUILD index 313a92f2b7e5..05b809671385 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/BUILD +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/BUILD @@ -24,10 +24,10 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/schemaconv:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/merge:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/typed:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/value:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/merge:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/typed:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/value:go_default_library", ], ) @@ -52,9 +52,9 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/merge:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v3/typed:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/merge:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/typed:go_default_library", "//vendor/sigs.k8s.io/yaml:go_default_library", ], ) diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/conflict.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/conflict.go index 2bc0d0ad8a8b..cfa19d8d9aa1 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/conflict.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/conflict.go @@ -25,8 +25,8 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/merge" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" ) // NewConflictError returns an error including details on the requests apply conflicts diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/fields.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/fields.go index 60117211a6ac..08186191a71c 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/fields.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/fields.go @@ -21,7 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) // EmptyFields represents a set with no paths diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go index f917fcd435aa..5e2f82c75069 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go @@ -22,7 +22,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kube-openapi/pkg/schemaconv" "k8s.io/kube-openapi/pkg/util/proto" - "sigs.k8s.io/structured-merge-diff/v3/typed" + "sigs.k8s.io/structured-merge-diff/v4/typed" ) // groupVersionKindExtensionKey is the key used to lookup the diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go index c5434b101e09..9a625e2acf77 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) // ManagedInterface groups a fieldpath.ManagedFields together with the timestamps associated with each operation. diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/pathelement.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/pathelement.go index 393420a70b0e..1954d65d32e3 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/pathelement.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/pathelement.go @@ -23,8 +23,8 @@ import ( "strconv" "strings" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/value" ) const ( diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go index 7b87009a16ff..6669665dde9d 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go @@ -23,8 +23,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kube-openapi/pkg/util/proto" - "sigs.k8s.io/structured-merge-diff/v3/typed" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/typed" + "sigs.k8s.io/structured-merge-diff/v4/value" ) // TypeConverter allows you to convert from runtime.Object to diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go index 15628b0275e2..fc59f2f0ef08 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go @@ -19,9 +19,9 @@ package internal import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/merge" - "sigs.k8s.io/structured-merge-diff/v3/typed" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" + "sigs.k8s.io/structured-merge-diff/v4/typed" ) // versionConverter is an implementation of diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go index 2fb54d9e1113..7c4079a6e6f5 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go @@ -26,8 +26,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/merge" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" ) type lastAppliedManager struct { diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater.go index a015e002ae03..b3ecd6393335 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater.go @@ -21,7 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) type managedFieldsUpdater struct { diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/stripmeta.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/stripmeta.go index fc8ee9b5833e..1460d9c80217 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/stripmeta.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/stripmeta.go @@ -20,7 +20,7 @@ import ( "fmt" "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) type stripMetaManager struct { diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go index 2cab9b311e55..a4761d3acd4d 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go @@ -24,8 +24,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/merge" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" ) type structuredMergeManager struct { diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go index b7c59cfc54d8..65cb389e517d 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go @@ -96,9 +96,11 @@ func SerializeObject(mediaType string, encoder runtime.Encoder, hw http.Response err := encoder.Encode(object, w) if err == nil { err = w.Close() - if err == nil { - return + if err != nil { + // we cannot write an error to the writer anymore as the Encode call was successful. + utilruntime.HandleError(fmt.Errorf("apiserver was unable to close cleanly the response writer: %v", err)) } + return } // make a best effort to write the object if a failure is detected diff --git a/vendor/k8s.io/apiserver/pkg/server/config.go b/vendor/k8s.io/apiserver/pkg/server/config.go index 4e9ec3711e81..07393938238a 100644 --- a/vendor/k8s.io/apiserver/pkg/server/config.go +++ b/vendor/k8s.io/apiserver/pkg/server/config.go @@ -692,11 +692,11 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G if err != nil { return nil, err } - // TODO: Once we get rid of /healthz consider changing this to post-start-hook. - err = s.addReadyzChecks(healthz.NewInformerSyncHealthz(c.SharedInformerFactory)) - if err != nil { - return nil, err - } + } + // TODO: Once we get rid of /healthz consider changing this to post-start-hook. + err := s.addReadyzChecks(healthz.NewInformerSyncHealthz(c.SharedInformerFactory)) + if err != nil { + return nil, err } } @@ -704,6 +704,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G if s.isPostStartHookRegistered(priorityAndFairnessConfigConsumerHookName) { } else if c.FlowControl != nil { err := s.AddPostStartHook(priorityAndFairnessConfigConsumerHookName, func(context PostStartHookContext) error { + go c.FlowControl.MaintainObservations(context.StopCh) go c.FlowControl.Run(context.StopCh) return nil }) diff --git a/vendor/k8s.io/apiserver/pkg/server/filters/priority-and-fairness.go b/vendor/k8s.io/apiserver/pkg/server/filters/priority-and-fairness.go index 224f371374a4..339b1e2c59bb 100644 --- a/vendor/k8s.io/apiserver/pkg/server/filters/priority-and-fairness.go +++ b/vendor/k8s.io/apiserver/pkg/server/filters/priority-and-fairness.go @@ -144,6 +144,7 @@ func WithPriorityAndFairness( } }, execute) if !served { + epmetrics.RecordRequestTermination(r, requestInfo, epmetrics.APIServerComponent, http.StatusTooManyRequests) tooManyRequests(r, w) } diff --git a/vendor/k8s.io/apiserver/pkg/server/healthz/BUILD b/vendor/k8s.io/apiserver/pkg/server/healthz/BUILD index c42813c96e9e..2b2c2cfb92e4 100644 --- a/vendor/k8s.io/apiserver/pkg/server/healthz/BUILD +++ b/vendor/k8s.io/apiserver/pkg/server/healthz/BUILD @@ -11,6 +11,7 @@ go_test( srcs = ["healthz_test.go"], embed = [":go_default_library"], deps = [ + "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/metrics:go_default_library", "//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library", @@ -31,7 +32,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/metrics:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/httplog:go_default_library", - "//staging/src/k8s.io/client-go/informers:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library", ], ) diff --git a/vendor/k8s.io/apiserver/pkg/server/healthz/healthz.go b/vendor/k8s.io/apiserver/pkg/server/healthz/healthz.go index f22bbfcadabc..b2d0007f54cb 100644 --- a/vendor/k8s.io/apiserver/pkg/server/healthz/healthz.go +++ b/vendor/k8s.io/apiserver/pkg/server/healthz/healthz.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "net/http" + "reflect" "strings" "sync" "sync/atomic" @@ -29,7 +30,6 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/endpoints/metrics" "k8s.io/apiserver/pkg/server/httplog" - "k8s.io/client-go/informers" "k8s.io/klog/v2" ) @@ -82,16 +82,20 @@ func (l *log) Check(_ *http.Request) error { return fmt.Errorf("logging blocked") } +type cacheSyncWaiter interface { + WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool +} + type informerSync struct { - sharedInformerFactory informers.SharedInformerFactory + cacheSyncWaiter cacheSyncWaiter } var _ HealthChecker = &informerSync{} -// NewInformerSyncHealthz returns a new HealthChecker that will pass only if all informers in the given sharedInformerFactory sync. -func NewInformerSyncHealthz(sharedInformerFactory informers.SharedInformerFactory) HealthChecker { +// NewInformerSyncHealthz returns a new HealthChecker that will pass only if all informers in the given cacheSyncWaiter sync. +func NewInformerSyncHealthz(cacheSyncWaiter cacheSyncWaiter) HealthChecker { return &informerSync{ - sharedInformerFactory: sharedInformerFactory, + cacheSyncWaiter: cacheSyncWaiter, } } @@ -104,8 +108,8 @@ func (i *informerSync) Check(_ *http.Request) error { // Close stopCh to force checking if informers are synced now. close(stopCh) - var informersByStarted map[bool][]string - for informerType, started := range i.sharedInformerFactory.WaitForCacheSync(stopCh) { + informersByStarted := make(map[bool][]string) + for informerType, started := range i.cacheSyncWaiter.WaitForCacheSync(stopCh) { informersByStarted[started] = append(informersByStarted[started], informerType.String()) } diff --git a/vendor/k8s.io/apiserver/pkg/server/options/BUILD b/vendor/k8s.io/apiserver/pkg/server/options/BUILD index 63df0c137360..84a507fe4444 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/BUILD +++ b/vendor/k8s.io/apiserver/pkg/server/options/BUILD @@ -88,6 +88,9 @@ go_library( "//vendor/k8s.io/kube-openapi/pkg/common:go_default_library", "//vendor/k8s.io/utils/path:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//vendor/golang.org/x/sys/unix:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//vendor/golang.org/x/sys/unix:go_default_library", ], @@ -100,9 +103,15 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//vendor/golang.org/x/sys/unix:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//vendor/golang.org/x/sys/unix:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//vendor/golang.org/x/sys/unix:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//vendor/golang.org/x/sys/unix:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//vendor/golang.org/x/sys/unix:go_default_library", ], diff --git a/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go b/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go index c0d78eb5eb48..e1cb4a6fbfa8 100644 --- a/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go +++ b/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go @@ -36,6 +36,18 @@ type OpenAPI struct { // Install adds the SwaggerUI webservice to the given mux. func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) (*handler.OpenAPIService, *spec.Swagger) { + // we shadow ClustResourceQuotas, RoleBindingRestrictions, and SecurityContextContstraints + // with a CRD. This loop removes all CRQ,RBR, SCC paths + // from the OpenAPI spec such that they don't conflict with the CRD + // apiextensions-apiserver spec during merging. + oa.Config.IgnorePrefixes = append(oa.Config.IgnorePrefixes, + "/apis/quota.openshift.io/v1/clusterresourcequotas", + "/apis/security.openshift.io/v1/securitycontextconstraints", + "/apis/authorization.openshift.io/v1/rolebindingrestrictions", + "/apis/authorization.openshift.io/v1/namespaces/{namespace}/rolebindingrestrictions", + "/apis/authorization.openshift.io/v1/watch/namespaces/{namespace}/rolebindingrestrictions", + "/apis/authorization.openshift.io/v1/watch/rolebindingrestrictions") + spec, err := builder.BuildOpenAPISpec(c.RegisteredWebServices(), oa.Config) if err != nil { klog.Fatalf("Failed to build open api spec for root: %v", err) diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/etcd3retry/retry_etcdclient.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/etcd3retry/retry_etcdclient.go new file mode 100644 index 000000000000..5d3597786a32 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/etcd3retry/retry_etcdclient.go @@ -0,0 +1,243 @@ +package etcd3retry + +import ( + "context" + "time" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" + "k8s.io/klog/v2" + + "google.golang.org/grpc/codes" +) + +var defaultRetry = wait.Backoff{ + Duration: 300 * time.Millisecond, + Factor: 2, // double the timeout for every failure + Jitter: 0.1, + Steps: 5, // .3 + .6 + 1.2 + 2.4 = 5ish this let's us smooth out short bumps but not long ones and keeps retry behavior closer. +} + +type retryClient struct { + // embed because we only want to override a few states + storage.Interface +} + +// New returns an etcd3 implementation of storage.Interface. +func NewRetryingEtcdStorage(delegate storage.Interface) storage.Interface { + return &retryClient{Interface: delegate} +} + +// Create adds a new object at a key unless it already exists. 'ttl' is time-to-live +// in seconds (0 means forever). If no error is returned and out is not nil, out will be +// set to the read value from database. +func (c *retryClient) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { + return onError(ctx, defaultRetry, isRetriableEtcdError, func() error { + return c.Interface.Create(ctx, key, obj, out, ttl) + }) +} + +// Delete removes the specified key and returns the value that existed at that spot. +// If key didn't exist, it will return NotFound storage error. +func (c *retryClient) Delete(ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, validateDeletion storage.ValidateObjectFunc) error { + return onError(ctx, defaultRetry, isRetriableEtcdError, func() error { + return c.Interface.Delete(ctx, key, out, preconditions, validateDeletion) + }) +} + +// Watch begins watching the specified key. Events are decoded into API objects, +// and any items selected by 'p' are sent down to returned watch.Interface. +// resourceVersion may be used to specify what version to begin watching, +// which should be the current resourceVersion, and no longer rv+1 +// (e.g. reconnecting without missing any updates). +// If resource version is "0", this interface will get current object at given key +// and send it in an "ADDED" event, before watch starts. +func (c *retryClient) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { + var ret watch.Interface + err := onError(ctx, defaultRetry, isRetriableEtcdError, func() error { + var innerErr error + ret, innerErr = c.Interface.Watch(ctx, key, opts) + return innerErr + }) + return ret, err +} + +// WatchList begins watching the specified key's items. Items are decoded into API +// objects and any item selected by 'p' are sent down to returned watch.Interface. +// resourceVersion may be used to specify what version to begin watching, +// which should be the current resourceVersion, and no longer rv+1 +// (e.g. reconnecting without missing any updates). +// If resource version is "0", this interface will list current objects directory defined by key +// and send them in "ADDED" events, before watch starts. +func (c *retryClient) WatchList(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { + var ret watch.Interface + err := onError(ctx, defaultRetry, isRetriableEtcdError, func() error { + var innerErr error + ret, innerErr = c.Interface.WatchList(ctx, key, opts) + return innerErr + }) + return ret, err +} + +// Get unmarshals json found at key into objPtr. On a not found error, will either +// return a zero object of the requested type, or an error, depending on 'opts.ignoreNotFound'. +// Treats empty responses and nil response nodes exactly like a not found error. +// The returned contents may be delayed, but it is guaranteed that they will +// match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'. +func (c *retryClient) Get(ctx context.Context, key string, opts storage.GetOptions, objPtr runtime.Object) error { + return onError(ctx, defaultRetry, isRetriableEtcdError, func() error { + return c.Interface.Get(ctx, key, opts, objPtr) + }) +} + +// GetToList unmarshals json found at key and opaque it into *List api object +// (an object that satisfies the runtime.IsList definition). +// The returned contents may be delayed, but it is guaranteed that they will +// match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'. +func (c *retryClient) GetToList(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error { + return onError(ctx, defaultRetry, isRetriableEtcdError, func() error { + return c.Interface.GetToList(ctx, key, opts, listObj) + }) +} + +// List unmarshalls jsons found at directory defined by key and opaque them +// into *List api object (an object that satisfies runtime.IsList definition). +// The returned contents may be delayed, but it is guaranteed that they will +// match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'. +func (c *retryClient) List(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error { + return onError(ctx, defaultRetry, isRetriableEtcdError, func() error { + return c.Interface.List(ctx, key, opts, listObj) + }) +} + +// GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'ptrToType') +// retrying the update until success if there is index conflict. +// Note that object passed to tryUpdate may change across invocations of tryUpdate() if +// other writers are simultaneously updating it, so tryUpdate() needs to take into account +// the current contents of the object when deciding how the update object should look. +// If the key doesn't exist, it will return NotFound storage error if ignoreNotFound=false +// or zero value in 'ptrToType' parameter otherwise. +// If the object to update has the same value as previous, it won't do any update +// but will return the object in 'ptrToType' parameter. +// If 'suggestion' can contain zero or one element - in such case this can be used as +// a suggestion about the current version of the object to avoid read operation from +// storage to get it. +// +// Example: +// +// s := /* implementation of Interface */ +// err := s.GuaranteedUpdate( +// "myKey", &MyType{}, true, +// func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) { +// // Before each invocation of the user defined function, "input" is reset to +// // current contents for "myKey" in database. +// curr := input.(*MyType) // Guaranteed to succeed. +// +// // Make the modification +// curr.Counter++ +// +// // Return the modified object - return an error to stop iterating. Return +// // a uint64 to alter the TTL on the object, or nil to keep it the same value. +// return cur, nil, nil +// }, +// ) +func (c *retryClient) GuaranteedUpdate( + ctx context.Context, key string, ptrToType runtime.Object, ignoreNotFound bool, + precondtions *storage.Preconditions, tryUpdate storage.UpdateFunc, suggestion ...runtime.Object) error { + return onError(ctx, defaultRetry, isRetriableEtcdError, func() error { + return c.Interface.GuaranteedUpdate(ctx, key, ptrToType, ignoreNotFound, precondtions, tryUpdate, suggestion...) + }) +} + +// isRetriableEtcdError returns true if a retry should be attempted, otherwise false. +// errorLabel is set to a non-empty value that reflects the type of error encountered. +func isRetriableEtcdError(err error) (errorLabel string, retry bool) { + if err == nil { + return + } + + etcdError, ok := err.(interface { + error + Code() codes.Code + }) + switch { + case ok && etcdError.Code() == codes.Unavailable: + errorLabel = "Unavailable" + retry = true + case ok: + // any other error, we don't retry + return + + // TODO: we need to figure out whether it is applicable to etcd. We don't retry on "connection refused" + // error as it is not deemed transient. How about "EOF"? + case net.IsConnectionReset(err): + errorLabel = "ConnectionReset" + retry = true + } + + return +} + +func neverRetry(_ error) (string, bool) { + // TODO this needs a metric + return "", false +} + +// onError allows the caller to retry fn in case the error returned by fn is retriable +// according to the provided function. backoff defines the maximum retries and the wait +// interval between two retries. +func onError(ctx context.Context, backoff wait.Backoff, retriable func(error) (string, bool), fn func() error) error { + var lastErr error + var lastErrLabel string + var retry bool + err := backoffWithRequestContext(ctx, backoff, func() (bool, error) { + err := fn() + if retry { + // TODO: reduce verbosity once debugging in ci (upgrade tests) is done. + klog.V(1).Infof("etcd retry - lastErrLabel: %s error:%v", lastErrLabel, err) + metrics.UpdateEtcdRequestRetry(lastErrLabel) + } + if err == nil { + return true, nil + } + + lastErrLabel, retry = retriable(err) + if retry { + lastErr = err + return false, nil + } + + return false, err + }) + if err == wait.ErrWaitTimeout && lastErr != nil { + err = lastErr + } + return err +} + +// backoffWithRequestContext works with a request context and a Backoff. It ensures that the retry wait never +// exceeds the deadline specified by the request context. +func backoffWithRequestContext(ctx context.Context, backoff wait.Backoff, condition wait.ConditionFunc) error { + for backoff.Steps > 0 { + if ok, err := condition(); err != nil || ok { + return err + } + + if backoff.Steps == 1 { + break + } + + waitBeforeRetry := backoff.Step() + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(waitBeforeRetry): + } + } + + return wait.ErrWaitTimeout +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go index a0de7e18cec6..791d1e5c5e2f 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go @@ -35,8 +35,12 @@ import ( var ( etcdRequestLatency = compbasemetrics.NewHistogramVec( &compbasemetrics.HistogramOpts{ - Name: "etcd_request_duration_seconds", - Help: "Etcd request latency in seconds for each operation and object type.", + Name: "etcd_request_duration_seconds", + Help: "Etcd request latency in seconds for each operation and object type.", + // Keeping it similar to the buckets used by the apiserver_request_duration_seconds metric so that + // api latency and etcd latency can be more comparable side by side. + Buckets: []float64{.005, .01, .025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, + 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60}, StabilityLevel: compbasemetrics.ALPHA, }, []string{"operation", "type"}, @@ -57,6 +61,14 @@ var ( }, []string{"endpoint"}, ) + etcdRequestRetry = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "etcd_request_retry_total", + Help: "Etcd request retry total", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"error"}, + ) ) var registerMetrics sync.Once @@ -68,6 +80,7 @@ func Register() { legacyregistry.MustRegister(etcdRequestLatency) legacyregistry.MustRegister(objectCounts) legacyregistry.MustRegister(dbTotalSize) + legacyregistry.MustRegister(etcdRequestRetry) }) } @@ -95,3 +108,8 @@ func sinceInSeconds(start time.Time) float64 { func UpdateEtcdDbSize(ep string, size int64) { dbTotalSize.WithLabelValues(ep).Set(float64(size)) } + +// UpdateEtcdRequestRetry sets the etcd_request_retry_total metric. +func UpdateEtcdRequestRetry(errorCode string) { + etcdRequestRetry.WithLabelValues(errorCode).Inc() +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go index 812cfc69c6c0..14643dad913d 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -572,7 +572,7 @@ func (s *store) List(ctx context.Context, key string, opts storage.ListOptions, fromRV = &parsedRV } - var returnedRV, continueRV int64 + var returnedRV, continueRV, withRev int64 var continueKey string switch { case s.pagingEnabled && len(pred.Continue) > 0: @@ -593,7 +593,7 @@ func (s *store) List(ctx context.Context, key string, opts storage.ListOptions, // continueRV==0 is invalid. // If continueRV < 0, the request is for the latest resource version. if continueRV > 0 { - options = append(options, clientv3.WithRev(continueRV)) + withRev = continueRV returnedRV = continueRV } case s.pagingEnabled && pred.Limit > 0: @@ -604,11 +604,11 @@ func (s *store) List(ctx context.Context, key string, opts storage.ListOptions, // and returnedRV is then set to the revision we get from the etcd response. case metav1.ResourceVersionMatchExact: returnedRV = int64(*fromRV) - options = append(options, clientv3.WithRev(returnedRV)) + withRev = returnedRV case "": // legacy case if *fromRV > 0 { returnedRV = int64(*fromRV) - options = append(options, clientv3.WithRev(returnedRV)) + withRev = returnedRV } default: return fmt.Errorf("unknown ResourceVersionMatch value: %v", match) @@ -625,7 +625,7 @@ func (s *store) List(ctx context.Context, key string, opts storage.ListOptions, // and returnedRV is then set to the revision we get from the etcd response. case metav1.ResourceVersionMatchExact: returnedRV = int64(*fromRV) - options = append(options, clientv3.WithRev(returnedRV)) + withRev = returnedRV case "": // legacy case default: return fmt.Errorf("unknown ResourceVersionMatch value: %v", match) @@ -634,6 +634,9 @@ func (s *store) List(ctx context.Context, key string, opts storage.ListOptions, options = append(options, clientv3.WithPrefix()) } + if withRev != 0 { + options = append(options, clientv3.WithRev(withRev)) + } // loop until we have filled the requested limit from etcd or there are no more results var lastKey []byte @@ -695,6 +698,10 @@ func (s *store) List(ctx context.Context, key string, opts storage.ListOptions, break } key = string(lastKey) + "\x00" + if withRev == 0 { + withRev = returnedRV + options = append(options, clientv3.WithRev(withRev)) + } } // instruct the client to begin querying from immediately after the last key we returned diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go index bfb4820f2a85..887ebb6543c2 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go @@ -26,6 +26,8 @@ import ( "sync/atomic" "time" + "k8s.io/apiserver/pkg/storage/etcd3/etcd3retry" + grpcprom "github.com/grpc-ecosystem/go-grpc-prometheus" "go.etcd.io/etcd/clientv3" "go.etcd.io/etcd/pkg/transport" @@ -249,7 +251,7 @@ func newETCD3Storage(c storagebackend.Config) (storage.Interface, DestroyFunc, e if transformer == nil { transformer = value.IdentityTransformer } - return etcd3.New(client, c.Codec, c.Prefix, transformer, c.Paging), destroyFunc, nil + return etcd3retry.NewRetryingEtcdStorage(etcd3.New(client, c.Codec, c.Prefix, transformer, c.Paging)), destroyFunc, nil } // startDBSizeMonitorPerEndpoint starts a loop to monitor etcd database size and update the diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/BUILD b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/BUILD index 481342ca0321..a2307920c088 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/BUILD +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/BUILD @@ -38,6 +38,10 @@ go_test( "//staging/src/k8s.io/apiserver/pkg/storage/value:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/aes:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing:go_default_library", @@ -54,10 +58,18 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing:go_default_library", diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go index 91f357023433..50eb33272168 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go @@ -227,6 +227,23 @@ func (cfgCtlr *configController) initializeConfigController(informerFactory kube }}) } +// MaintainObservations keeps the observers from +// metrics.PriorityLevelConcurrencyObserverPairGenerator from falling +// too far behind +func (cfgCtlr *configController) MaintainObservations(stopCh <-chan struct{}) { + wait.Until(cfgCtlr.updateObservations, 10*time.Second, stopCh) +} + +func (cfgCtlr *configController) updateObservations() { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + for _, plc := range cfgCtlr.priorityLevelStates { + if plc.queues != nil { + plc.queues.UpdateObservations() + } + } +} + func (cfgCtlr *configController) Run(stopCh <-chan struct{}) error { defer cfgCtlr.configQueue.ShutDown() klog.Info("Starting API Priority and Fairness config controller") diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go index 04d4df7c73c8..b7c9164c2f7c 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go @@ -58,7 +58,7 @@ func (cfgCtlr *configController) dumpPriorityLevels(w http.ResponseWriter, r *ht "ExecutingRequests", // 6 } tabPrint(tabWriter, rowForHeaders(columnHeaders)) - endline(tabWriter) + endLine(tabWriter) for _, plState := range cfgCtlr.priorityLevelStates { if plState.queues == nil { tabPrint(tabWriter, row( @@ -69,7 +69,7 @@ func (cfgCtlr *configController) dumpPriorityLevels(w http.ResponseWriter, r *ht "", // 5 "", // 6 )) - endline(tabWriter) + endLine(tabWriter) continue } queueSetDigest := plState.queues.Dump(false) @@ -88,7 +88,7 @@ func (cfgCtlr *configController) dumpPriorityLevels(w http.ResponseWriter, r *ht queueSetDigest.Waiting, // 5 queueSetDigest.Executing, // 6 )) - endline(tabWriter) + endLine(tabWriter) } runtime.HandleError(tabWriter.Flush()) } @@ -105,7 +105,7 @@ func (cfgCtlr *configController) dumpQueues(w http.ResponseWriter, r *http.Reque "VirtualStart", // 5 } tabPrint(tabWriter, rowForHeaders(columnHeaders)) - endline(tabWriter) + endLine(tabWriter) for _, plState := range cfgCtlr.priorityLevelStates { if plState.queues == nil { tabPrint(tabWriter, row( @@ -115,7 +115,7 @@ func (cfgCtlr *configController) dumpQueues(w http.ResponseWriter, r *http.Reque "", // 4 "", // 5 )) - endline(tabWriter) + endLine(tabWriter) continue } queueSetDigest := plState.queues.Dump(false) @@ -127,7 +127,7 @@ func (cfgCtlr *configController) dumpQueues(w http.ResponseWriter, r *http.Reque q.ExecutingRequests, // 4 q.VirtualStart, // 5 )) - endline(tabWriter) + endLine(tabWriter) } } runtime.HandleError(tabWriter.Flush()) @@ -149,6 +149,7 @@ func (cfgCtlr *configController) dumpRequests(w http.ResponseWriter, r *http.Req "ArriveTime", // 6 })) if includeRequestDetails { + continueLine(tabWriter) tabPrint(tabWriter, rowForHeaders([]string{ "UserName", // 7 "Verb", // 8 @@ -160,7 +161,7 @@ func (cfgCtlr *configController) dumpRequests(w http.ResponseWriter, r *http.Req "SubResource", // 14 })) } - endline(tabWriter) + endLine(tabWriter) for _, plState := range cfgCtlr.priorityLevelStates { if plState.queues == nil { tabPrint(tabWriter, row( @@ -172,6 +173,7 @@ func (cfgCtlr *configController) dumpRequests(w http.ResponseWriter, r *http.Req "", // 6 )) if includeRequestDetails { + continueLine(tabWriter) tabPrint(tabWriter, row( "", // 7 "", // 8 @@ -183,7 +185,7 @@ func (cfgCtlr *configController) dumpRequests(w http.ResponseWriter, r *http.Req "", // 14 )) } - endline(tabWriter) + endLine(tabWriter) continue } queueSetDigest := plState.queues.Dump(includeRequestDetails) @@ -198,6 +200,7 @@ func (cfgCtlr *configController) dumpRequests(w http.ResponseWriter, r *http.Req r.ArriveTime, // 6 )) if includeRequestDetails { + continueLine(tabWriter) tabPrint(tabWriter, rowForRequestDetails( r.UserName, // 7 r.RequestInfo.Verb, // 8 @@ -212,7 +215,7 @@ func (cfgCtlr *configController) dumpRequests(w http.ResponseWriter, r *http.Req r.RequestInfo.Subresource, // 14 )) } - endline(tabWriter) + endLine(tabWriter) } } } @@ -223,7 +226,12 @@ func tabPrint(w io.Writer, row string) { _, err := fmt.Fprint(w, row) runtime.HandleError(err) } -func endline(w io.Writer) { + +func continueLine(w io.Writer) { + _, err := fmt.Fprint(w, ",\t") + runtime.HandleError(err) +} +func endLine(w io.Writer) { _, err := fmt.Fprint(w, "\n") runtime.HandleError(err) } @@ -269,9 +277,14 @@ func rowForRequestDetails(username, verb, path, namespace, name, apiVersion, res username, verb, path, + namespace, + name, + apiVersion, + resource, + subResource, ) } func row(columns ...string) string { - return strings.Join(columns, ",\t") + ",\t" + return strings.Join(columns, ",\t") } diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go index 99c36005be2c..5b8c0391684c 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go @@ -38,10 +38,13 @@ import ( type Interface interface { // Handle takes care of queuing and dispatching a request // characterized by the given digest. The given `noteFn` will be - // invoked with the results of request classification. If Handle - // decides that the request should be executed then `execute()` - // will be invoked once to execute the request; otherwise - // `execute()` will not be invoked. + // invoked with the results of request classification. If the + // request is queued then `queueNoteFn` will be called twice, + // first with `true` and then with `false`; otherwise + // `queueNoteFn` will not be called at all. If Handle decides + // that the request should be executed then `execute()` will be + // invoked once to execute the request; otherwise `execute()` will + // not be invoked. Handle(ctx context.Context, requestDigest RequestDigest, noteFn func(fs *fctypesv1a1.FlowSchema, pl *fctypesv1a1.PriorityLevelConfiguration), @@ -49,6 +52,9 @@ type Interface interface { execFn func(), ) + // MaintainObservations is a helper for maintaining statistics. + MaintainObservations(stopCh <-chan struct{}) + // Run monitors config objects from the main apiservers and causes // any needed changes to local behavior. This method ceases // activity and returns after the given channel is closed. diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go index e0b628ecd0fe..882a505c81f6 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go @@ -82,6 +82,10 @@ type QueueSet interface { // exactly once. StartRequest(ctx context.Context, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn QueueNoteFn) (req Request, idle bool) + // UpdateObservations makes sure any time-based statistics have + // caught up with the current clock reading + UpdateObservations() + // Dump saves and returns the instant internal state of the queue-set. // Note that dumping process will stop the queue-set from proceeding // any requests. diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go index adcb56d856a0..b469a4ac5752 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go @@ -743,6 +743,11 @@ func (qs *queueSet) goroutineDoneOrBlocked() { qs.counter.Add(-1) } +func (qs *queueSet) UpdateObservations() { + qs.obsPair.RequestsWaiting.Add(0) + qs.obsPair.RequestsExecuting.Add(0) +} + func (qs *queueSet) Dump(includeRequestDetails bool) debug.QueueSetDump { qs.lock.Lock() defer qs.lock.Unlock() diff --git a/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go b/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go index 6e01066b0b08..9de389fa7e4d 100644 --- a/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go +++ b/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go @@ -19,8 +19,6 @@ package memory import ( "errors" "fmt" - "net" - "net/url" "sync" "syscall" @@ -64,19 +62,11 @@ var _ discovery.CachedDiscoveryInterface = &memCacheClient{} // "Connection reset" error which usually means that apiserver is temporarily // unavailable. func isTransientConnectionError(err error) bool { - urlError, ok := err.(*url.Error) - if !ok { - return false - } - opError, ok := urlError.Err.(*net.OpError) - if !ok { - return false - } - errno, ok := opError.Err.(syscall.Errno) - if !ok { - return false + var errno syscall.Errno + if errors.As(err, &errno) { + return errno == syscall.ECONNREFUSED || errno == syscall.ECONNRESET } - return errno == syscall.ECONNREFUSED || errno == syscall.ECONNRESET + return false } func isTransientError(err error) bool { diff --git a/vendor/k8s.io/client-go/util/jsonpath/parser.go b/vendor/k8s.io/client-go/util/jsonpath/parser.go index e1aab6804f81..b84016a9f9ce 100644 --- a/vendor/k8s.io/client-go/util/jsonpath/parser.go +++ b/vendor/k8s.io/client-go/util/jsonpath/parser.go @@ -214,8 +214,11 @@ func (p *Parser) parseIdentifier(cur *ListNode) error { return p.parseInsideAction(cur) } -// parseRecursive scans the recursive desent operator .. +// parseRecursive scans the recursive descent operator .. func (p *Parser) parseRecursive(cur *ListNode) error { + if lastIndex := len(cur.Nodes) - 1; lastIndex >= 0 && cur.Nodes[lastIndex].Type() == NodeRecursive { + return fmt.Errorf("invalid multiple recursive descent") + } p.pos += len("..") p.consumeText() cur.append(newRecursive()) diff --git a/vendor/k8s.io/cloud-provider/cloud.go b/vendor/k8s.io/cloud-provider/cloud.go index c39cf463d0f7..98fb5c347c84 100644 --- a/vendor/k8s.io/cloud-provider/cloud.go +++ b/vendor/k8s.io/cloud-provider/cloud.go @@ -49,8 +49,11 @@ type Interface interface { LoadBalancer() (LoadBalancer, bool) // Instances returns an instances interface. Also returns true if the interface is supported, false otherwise. Instances() (Instances, bool) - // InstancesV2 is an implementation for instances only used by cloud node-controller now. + // InstancesV2 is an implementation for instances and should only be implemented by external cloud providers. + // Implementing InstancesV2 is behaviorally identical to Instances but is optimized to significantly reduce + // API calls to the cloud provider when registering and syncing nodes. // Also returns true if the interface is supported, false otherwise. + // WARNING: InstancesV2 is an experimental interface and is subject to change in v1.20. InstancesV2() (InstancesV2, bool) // Zones returns a zones interface. Also returns true if the interface is supported, false otherwise. Zones() (Zones, bool) @@ -189,15 +192,20 @@ type Instances interface { InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) } -// InstancesV2 is an abstract, pluggable interface for sets of instances. -// Unlike Instances, it is only used by cloud node-controller now. +// InstancesV2 is an abstract, pluggable interface for cloud provider instances. +// Unlike the Instances interface, it is designed for external cloud providers and should only be used by them. +// WARNING: InstancesV2 is an experimental interface and is subject to change in v1.20. type InstancesV2 interface { - // InstanceExistsByProviderID returns true if the instance for the given provider exists. - InstanceExistsByProviderID(ctx context.Context, providerID string) (bool, error) - // InstanceShutdownByProviderID returns true if the instance is shutdown in cloudprovider. - InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) - // InstanceMetadataByProviderID returns the instance's metadata. - InstanceMetadataByProviderID(ctx context.Context, providerID string) (*InstanceMetadata, error) + // InstanceExists returns true if the instance for the given node exists according to the cloud provider. + // Use the node.name or node.spec.providerID field to find the node in the cloud provider. + InstanceExists(ctx context.Context, node *v1.Node) (bool, error) + // InstanceShutdown returns true if the instance is shutdown according to the cloud provider. + // Use the node.name or node.spec.providerID field to find the node in the cloud provider. + InstanceShutdown(ctx context.Context, node *v1.Node) (bool, error) + // InstanceMetadata returns the instance's metadata. The values returned in InstanceMetadata are + // translated into specific fields in the Node object on registration. + // Use the node.name or node.spec.providerID field to find the node in the cloud provider. + InstanceMetadata(ctx context.Context, node *v1.Node) (*InstanceMetadata, error) } // Route is a representation of an advanced routing rule. @@ -265,12 +273,25 @@ type PVLabeler interface { GetLabelsForVolume(ctx context.Context, pv *v1.PersistentVolume) (map[string]string, error) } -// InstanceMetadata contains metadata about the specific instance. +// InstanceMetadata contains metadata about a specific instance. +// Values returned in InstanceMetadata are translated into specific fields in Node. type InstanceMetadata struct { - // ProviderID is provider's id that instance belongs to. + // ProviderID is a unique ID used to idenfitify an instance on the cloud provider. + // The ProviderID set here will be set on the node's spec.providerID field. + // The provider ID format can be set by the cloud provider but providers should + // ensure the format does not change in any incompatible way. + // + // The provider ID format used by existing cloud provider has been: + // :// + // Existing providers setting this field should preserve the existing format + // currently being set in node.spec.providerID. ProviderID string - // Type is instance's type. - Type string + // InstanceType is the instance's type. + // The InstanceType set here will be set using the following labels on the node object: + // * node.kubernetes.io/instance-type= + // * beta.kubernetes.io/instance-type= (DEPRECATED) + InstanceType string // NodeAddress contains information for the instance's address. + // The node addresses returned here will be set on the node's status.addresses field. NodeAddresses []v1.NodeAddress } diff --git a/vendor/k8s.io/cloud-provider/go.mod b/vendor/k8s.io/cloud-provider/go.mod index 77b2eb465afd..4d9498c7c6f1 100644 --- a/vendor/k8s.io/cloud-provider/go.mod +++ b/vendor/k8s.io/cloud-provider/go.mod @@ -2,31 +2,26 @@ module k8s.io/cloud-provider -go 1.13 +go 1.15 require ( github.com/google/go-cmp v0.4.0 github.com/stretchr/testify v1.4.0 - k8s.io/api v0.19.0-rc.2 - k8s.io/apimachinery v0.19.0-rc.2 - k8s.io/client-go v0.19.0-rc.2 - k8s.io/component-base v0.19.0-rc.2 - k8s.io/klog/v2 v2.2.0 - k8s.io/utils v0.0.0-20200720150651-0bdb4ca86cbc + k8s.io/api v0.19.0 + k8s.io/apimachinery v0.19.0 + k8s.io/client-go v0.19.0 + k8s.io/component-base v0.19.0 + k8s.io/klog/v2 v2.3.0 + k8s.io/utils v0.0.0-20200729134348-d5654de09c73 ) replace ( github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc - github.com/coreos/etcd => github.com/coreos/etcd v3.3.10+incompatible - github.com/evanphx/json-patch => github.com/evanphx/json-patch v0.0.0-20190815234213-e83c0a1c26c8 github.com/go-bindata/go-bindata => github.com/go-bindata/go-bindata v3.1.1+incompatible - github.com/golang/glog => github.com/openshift/golang-glog v0.0.0-20190322123450-3c92600d7533 github.com/imdario/mergo => github.com/imdario/mergo v0.3.5 - github.com/onsi/ginkgo => github.com/openshift/onsi-ginkgo v4.5.0-origin.1+incompatible - github.com/openshift/build-machinery-go => github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc + github.com/onsi/ginkgo => github.com/openshift/ginkgo v4.5.0-origin.1+incompatible github.com/robfig/cron => github.com/robfig/cron v1.1.0 go.uber.org/multierr => go.uber.org/multierr v1.1.0 - golang.org/x/net => golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e gopkg.in/yaml.v2 => gopkg.in/yaml.v2 v2.2.8 k8s.io/api => ../api k8s.io/apiextensions-apiserver => ../apiextensions-apiserver @@ -40,6 +35,7 @@ replace ( k8s.io/component-base => ../component-base k8s.io/cri-api => ../cri-api k8s.io/csi-translation-lib => ../csi-translation-lib + k8s.io/klog/v2 => k8s.io/klog/v2 v2.2.0 k8s.io/kube-aggregator => ../kube-aggregator k8s.io/kube-controller-manager => ../kube-controller-manager k8s.io/kube-proxy => ../kube-proxy diff --git a/vendor/k8s.io/cloud-provider/go.sum b/vendor/k8s.io/cloud-provider/go.sum index 8fd8acfcc0aa..9e91812126e0 100644 --- a/vendor/k8s.io/cloud-provider/go.sum +++ b/vendor/k8s.io/cloud-provider/go.sum @@ -34,7 +34,7 @@ github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5 github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= +github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990/go.mod h1:ay/0dTb7NsG8QMDfsRfLHgZo/6xAJShLe1+ePPflihk= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -80,6 +80,7 @@ github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlR github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s= github.com/cilium/ebpf v0.0.0-20200601085316-9f1617e5c574/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s= github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= @@ -88,7 +89,7 @@ github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1w github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -146,8 +147,8 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= -github.com/evanphx/json-patch v0.0.0-20190815234213-e83c0a1c26c8 h1:DM7gHzQfHwIj+St8zaPOI6iQEPAxOwIkskvw6s9rDaM= -github.com/evanphx/json-patch v0.0.0-20190815234213-e83c0a1c26c8/go.mod h1:pmLOTb3x90VhIKxsA9yeQG5yfOkkKnkk1h+Ql8NDYDw= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -170,8 +171,6 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= @@ -219,13 +218,13 @@ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2K github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -325,6 +324,7 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -400,19 +400,19 @@ github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5X github.com/opencontainers/runc v0.0.0-20191031171055-b133feaeeb2e/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc90.0.20200616040943-82d2fa4eb069/go.mod h1:3Sm6Dt7OT8z88EbdQqqcRN2oCT54jbi72tT/HqgflT8= github.com/opencontainers/runc v1.0.0-rc91.0.20200707015106-819fcc687efb/go.mod h1:ZuXhqlr4EiRYgDrBDNfSbE4+n9JX4+V107NwAmF7sZA= -github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= -github.com/openshift/api v0.0.0-20200722170803-0ba2c3658da6/go.mod h1:IXsT3F4NjLtRzfnQvwU+g/oPWpoNsVV5vd5aaOMO8eU= -github.com/openshift/api v0.0.0-20200722204502-c33fd0aa6ffa/go.mod h1:IXsT3F4NjLtRzfnQvwU+g/oPWpoNsVV5vd5aaOMO8eU= -github.com/openshift/apiserver-library-go v0.0.0-20200723181026-dd21ec96ba0a/go.mod h1://gQP1LMTExUTcFCgJdKHY23UVHhkaQILXsTdVz0Qok= -github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc/go.mod h1:1CkcsT3aVebzRBzVTSbiKSkJMsC/CASqxesfqEMfJEc= -github.com/openshift/client-go v0.0.0-20200722173614-5a1b0aaeff15/go.mod h1:yd4Zpcdk+8JyMWi6v+h78jPqK0FvXbJY41Wq3SZxl+c= -github.com/openshift/golang-glog v0.0.0-20190322123450-3c92600d7533/go.mod h1:3sa6LKKRDnR1xy4Kn8htvPwqIOVwXh8fIU3LRY22q3U= -github.com/openshift/library-go v0.0.0-20200722204747-e3f2c82ff290/go.mod h1:/gVyoY2dl35bcCCgs+36UmGt6n/kn3f64hfDduujQ1c= -github.com/openshift/onsi-ginkgo v4.5.0-origin.1+incompatible h1:GtzyDU5vBFU40hz4GWd1qU5FJByNljWdgkM2LtdelGk= -github.com/openshift/onsi-ginkgo v4.5.0-origin.1+incompatible/go.mod h1:azqkkH4Vpp9A579CC26hicol/wViXag9rOwElif6v9E= +github.com/openshift/api v0.0.0-20200827090112-c05698d102cf/go.mod h1:M3xexPhgM8DISzzRpuFUy+jfPjQPIcs9yqEYj17mXV8= +github.com/openshift/api v0.0.0-20200829102639-8a3a835f1acf/go.mod h1:M3xexPhgM8DISzzRpuFUy+jfPjQPIcs9yqEYj17mXV8= +github.com/openshift/apiserver-library-go v0.0.0-20200901140731-1236dc23c728/go.mod h1:+B51GHs/jfZzk93MKrSSA8BWxrulVVcxiBG7kdFpd74= +github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= +github.com/openshift/client-go v0.0.0-20200827190008-3062137373b5/go.mod h1:5rGmrkQ8DJEUXA+AR3rEjfH+HFyg4/apY9iCQFgvPfE= +github.com/openshift/ginkgo v4.5.0-origin.1+incompatible h1:AGewrYJW8aXFkkf86sSoiO9L/a/QYKZvODVCaB/wk4o= +github.com/openshift/ginkgo v4.5.0-origin.1+incompatible/go.mod h1:8METQ1gDhl0KW+pGH4c0DIJYEN/ksVCL6hOuHPmXGnk= +github.com/openshift/library-go v0.0.0-20200831114015-2ab0c61c15de/go.mod h1:6vwp+YhYOIlj8MpkQKkebTTSn2TuYyvgiAFQ206jIEQ= +github.com/openshift/library-go v0.0.0-20200902112127-a4e32e339219/go.mod h1:6vwp+YhYOIlj8MpkQKkebTTSn2TuYyvgiAFQ206jIEQ= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -452,7 +452,6 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= -github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= @@ -498,9 +497,9 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= @@ -511,10 +510,11 @@ github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59b github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200716221620-18dfb9cca345/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -537,8 +537,8 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -563,8 +563,37 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -591,7 +620,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -607,6 +635,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -652,9 +681,10 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200602230032-c00d67ef29d0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -741,18 +771,15 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/kube-openapi v0.0.0-20200427153329-656914f816f9 h1:5NC2ITmvg8RoxoH0wgmL4zn4VZqXGsKbxrikjaQx6s4= -k8s.io/kube-openapi v0.0.0-20200427153329-656914f816f9/go.mod h1:bfCVj+qXcEaE5SCvzBaqpOySr6tuCcpPKqF6HD8nyCw= -k8s.io/kubernetes v1.19.0-rc.2/go.mod h1:zomfQQTZYrQjnakeJi8fHqMNyrDTT6F/MuLaeBHI9Xk= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= +k8s.io/kubernetes v1.19.0/go.mod h1:yhT1/ltQajQsha3tnYc9QPFYSumGM45nlZdjf7WqE1A= k8s.io/system-validators v1.1.2/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q= k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20200720150651-0bdb4ca86cbc h1:GiXZzevctVRRBh56shqcqB9s9ReWMU6GTsFyE2RCFJQ= -k8s.io/utils v0.0.0-20200720150651-0bdb4ca86cbc/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg= +k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= @@ -762,9 +789,8 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQbTRyDlZPJX2SUPEqvnB+j7AJjtlox7PEwigU0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v3 v3.0.1-0.20200706213357-43c19bbb7fba h1:AAbnc5KQuTWKuh2QSnyghKIOTFzB0Jayv7/OFDn3Cy4= -sigs.k8s.io/structured-merge-diff/v3 v3.0.1-0.20200706213357-43c19bbb7fba/go.mod h1:V06abazjHneE37ZdSY/UUwPVgcJMKI/jU5XGUjgIKoc= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go index ae2b861382b1..49f1f2dd2d87 100644 --- a/vendor/k8s.io/klog/v2/klog.go +++ b/vendor/k8s.io/klog/v2/klog.go @@ -1324,14 +1324,21 @@ func (v Verbose) InfoS(msg string, keysAndValues ...interface{}) { } } -// Error is equivalent to the global Error function, guarded by the value of v. -// See the documentation of V for usage. +// Deprecated: Use ErrorS instead. func (v Verbose) Error(err error, msg string, args ...interface{}) { if v.enabled { logging.errorS(err, v.logr, msg, args...) } } +// ErrorS is equivalent to the global Error function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) ErrorS(err error, msg string, keysAndValues ...interface{}) { + if v.enabled { + logging.errorS(err, v.logr, msg, keysAndValues...) + } +} + // Info logs to the INFO log. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing. func Info(args ...interface{}) { diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go index c51239c28a71..1e9c03737586 100644 --- a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go @@ -24,7 +24,7 @@ import ( "strings" "k8s.io/kube-openapi/pkg/util/proto" - "sigs.k8s.io/structured-merge-diff/v3/schema" + "sigs.k8s.io/structured-merge-diff/v4/schema" ) // ToSchema converts openapi definitions into a schema suitable for structured @@ -263,7 +263,7 @@ func makeUnion(extensions map[string]interface{}) (schema.Union, error) { return schema.Union{}, fmt.Errorf(`"fields-to-discriminateBy"/%v: value must be a string, got: %#v`, field, value) } union.Fields = append(union.Fields, schema.UnionField{ - FieldName: field, + FieldName: field, DiscriminatorValue: discriminated, }) diff --git a/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/BUILD b/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/BUILD index 5971ef20282a..4791670bdac3 100644 --- a/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/BUILD +++ b/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/BUILD @@ -77,6 +77,18 @@ go_library( "//vendor/k8s.io/utils/mount:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/proxy/metrics:go_default_library", + "//pkg/proxy/util/iptables:go_default_library", + "//pkg/util/node:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", + "//staging/src/k8s.io/client-go/tools/cache:go_default_library", + "//staging/src/k8s.io/client-go/tools/watch:go_default_library", + "//staging/src/k8s.io/component-base/metrics:go_default_library", + "//vendor/k8s.io/utils/net:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/proxy/metrics:go_default_library", "//pkg/proxy/util/iptables:go_default_library", @@ -125,6 +137,18 @@ go_library( "//staging/src/k8s.io/component-base/metrics:go_default_library", "//vendor/k8s.io/utils/net:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/proxy/metrics:go_default_library", + "//pkg/proxy/util/iptables:go_default_library", + "//pkg/util/node:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", + "//staging/src/k8s.io/client-go/tools/cache:go_default_library", + "//staging/src/k8s.io/client-go/tools/watch:go_default_library", + "//staging/src/k8s.io/component-base/metrics:go_default_library", + "//vendor/k8s.io/utils/net:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//pkg/proxy/metrics:go_default_library", "//pkg/proxy/util/iptables:go_default_library", @@ -137,6 +161,18 @@ go_library( "//staging/src/k8s.io/component-base/metrics:go_default_library", "//vendor/k8s.io/utils/net:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/proxy/metrics:go_default_library", + "//pkg/proxy/util/iptables:go_default_library", + "//pkg/util/node:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", + "//staging/src/k8s.io/client-go/tools/cache:go_default_library", + "//staging/src/k8s.io/client-go/tools/watch:go_default_library", + "//staging/src/k8s.io/component-base/metrics:go_default_library", + "//vendor/k8s.io/utils/net:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/proxy/metrics:go_default_library", "//pkg/proxy/util/iptables:go_default_library", @@ -239,6 +275,14 @@ go_test( "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/proxy/ipvs:go_default_library", + "//pkg/proxy/util/iptables:go_default_library", + "//pkg/util/iptables:go_default_library", + "//pkg/util/iptables/testing:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/proxy/ipvs:go_default_library", "//pkg/proxy/util/iptables:go_default_library", @@ -271,6 +315,14 @@ go_test( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/proxy/ipvs:go_default_library", + "//pkg/proxy/util/iptables:go_default_library", + "//pkg/util/iptables:go_default_library", + "//pkg/util/iptables/testing:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//pkg/proxy/ipvs:go_default_library", "//pkg/proxy/util/iptables:go_default_library", @@ -279,6 +331,14 @@ go_test( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/proxy/ipvs:go_default_library", + "//pkg/proxy/util/iptables:go_default_library", + "//pkg/util/iptables:go_default_library", + "//pkg/util/iptables/testing:go_default_library", + "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/proxy/ipvs:go_default_library", "//pkg/proxy/util/iptables:go_default_library", diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/BUILD b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/BUILD index 6962a7f9ee56..7029cec36851 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/BUILD +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/BUILD @@ -13,6 +13,7 @@ go_library( "globalflags.go", "globalflags_linux.go", "globalflags_other.go", + "globalflags_providers.go", "options.go", "osflags_others.go", "osflags_windows.go", diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags.go index 455605f4f01d..fdc20d181779 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags.go @@ -84,9 +84,7 @@ func addCredentialProviderFlags(fs *pflag.FlagSet) { global := pflag.CommandLine local := pflag.NewFlagSet(os.Args[0], pflag.ExitOnError) - // TODO(#58034): This is not a static file, so it's not quite as straightforward as --google-json-key. - // We need to figure out how ACR users can dynamically provide pull credentials before we can deprecate this. - pflagRegister(global, local, "azure-container-registry-config") + addLegacyCloudProviderCredentialProviderFlags(global, local) fs.AddFlagSet(local) } diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_providerless.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_providerless.go new file mode 100644 index 000000000000..7fba07df799f --- /dev/null +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_providerless.go @@ -0,0 +1,27 @@ +// +build providerless + +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package options + +import ( + "github.com/spf13/pflag" +) + +func addLegacyCloudProviderCredentialProviderFlags(global, local *pflag.FlagSet) { + // no-op when no legacy providers are compiled in +} diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_providers.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_providers.go new file mode 100644 index 000000000000..5d2dd44d3454 --- /dev/null +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_providers.go @@ -0,0 +1,29 @@ +// +build !providerless + +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package options + +import ( + "github.com/spf13/pflag" +) + +func addLegacyCloudProviderCredentialProviderFlags(global, local *pflag.FlagSet) { + // TODO(#58034): This is not a static file, so it's not quite as straightforward as --google-json-key. + // We need to figure out how ACR users can dynamically provide pull credentials before we can deprecate this. + pflagRegister(global, local, "azure-container-registry-config") +} diff --git a/vendor/k8s.io/kubernetes/openshift-hack/e2e/annotate/rules.go b/vendor/k8s.io/kubernetes/openshift-hack/e2e/annotate/rules.go index 262b965fc237..c5487ad59a36 100644 --- a/vendor/k8s.io/kubernetes/openshift-hack/e2e/annotate/rules.go +++ b/vendor/k8s.io/kubernetes/openshift-hack/e2e/annotate/rules.go @@ -19,7 +19,6 @@ var ( // BETA features in 1.19, enabled by default // Their enablement is tracked via bz's targeted at 4.6. - `\[Feature:ExpandCSIVolumes\]`, // https://bugzilla.redhat.com/show_bug.cgi?id=1861218 `\[Feature:SCTPConnectivity\]`, // https://bugzilla.redhat.com/show_bug.cgi?id=1861606 }, // tests for features that are not implemented in openshift @@ -90,24 +89,12 @@ var ( // A fix is in progress: https://github.com/openshift/origin/pull/24709 `Multi-AZ Clusters should spread the pods of a replication controller across zones`, - - // Fix is in progress upstream and tracked via https://bugzilla.redhat.com/show_bug.cgi?id=1861215 - `Secret should create a pod that reads a secret`, - - // disabled until oc and origin are on k8s 1.19 - workloads team - `should return command exit codes`, - - // Disabled as per networking team. Follow-up tracked via https://bugzilla.redhat.com/show_bug.cgi?id=1861214 - `EndpointSliceMirroring should mirror a custom Endpoints resource through create update and delete`, - - // Test passes but container it uses exits with non-zero. - // https://bugzilla.redhat.com/show_bug.cgi?id=1861526 - `ServiceAccounts should set ownership and permission when RunAsUser or FsGroup is present`, }, // tests that may work, but we don't support them "[Disabled:Unsupported]": { - `\[Driver: rbd\]`, // OpenShift 4.x does not support Ceph RBD (use CSI instead) - `\[Driver: ceph\]`, // OpenShift 4.x does not support CephFS (use CSI instead) + `\[Driver: rbd\]`, // OpenShift 4.x does not support Ceph RBD (use CSI instead) + `\[Driver: ceph\]`, // OpenShift 4.x does not support CephFS (use CSI instead) + `\[Feature:PodSecurityPolicy\]`, // OpenShift 4.x does not enable PSP by default }, // tests too slow to be part of conformance "[Slow]": { @@ -145,10 +132,6 @@ var ( }, "[Skipped:azure]": { "Networking should provide Internet connection for containers", // Azure does not allow ICMP traffic to internet. - - // openshift-tests cannot access Azure API to create in-line or pre-provisioned volumes, https://bugzilla.redhat.com/show_bug.cgi?id=1723603 - `\[sig-storage\] In-tree Volumes \[Driver: azure\] \[Testpattern: Inline-volume`, - `\[sig-storage\] In-tree Volumes \[Driver: azure\] \[Testpattern: Pre-provisioned PV`, }, "[Skipped:gce]": { // Requires creation of a different compute instance in a different zone and is not compatible with volumeBindingMode of WaitForFirstConsumer which we use in 4.x diff --git a/vendor/k8s.io/kubernetes/pkg/api/endpoints/BUILD b/vendor/k8s.io/kubernetes/pkg/api/endpoints/BUILD deleted file mode 100644 index 22edbf3918f3..000000000000 --- a/vendor/k8s.io/kubernetes/pkg/api/endpoints/BUILD +++ /dev/null @@ -1,42 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", - "go_test", -) - -go_library( - name = "go_default_library", - srcs = ["util.go"], - importpath = "k8s.io/kubernetes/pkg/api/endpoints", - deps = [ - "//pkg/apis/core:go_default_library", - "//pkg/util/hash:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", - ], -) - -go_test( - name = "go_default_test", - srcs = ["util_test.go"], - embed = [":go_default_library"], - deps = [ - "//pkg/apis/core:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", - "//vendor/github.com/davecgh/go-spew/spew:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], -) diff --git a/vendor/k8s.io/kubernetes/pkg/api/endpoints/OWNERS b/vendor/k8s.io/kubernetes/pkg/api/endpoints/OWNERS deleted file mode 100644 index 6802ec84f40c..000000000000 --- a/vendor/k8s.io/kubernetes/pkg/api/endpoints/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -reviewers: -- thockin -- smarterclayton -- mikedanese -- sttts -- resouer diff --git a/vendor/k8s.io/kubernetes/pkg/api/endpoints/util.go b/vendor/k8s.io/kubernetes/pkg/api/endpoints/util.go deleted file mode 100644 index 2c076f9afd1a..000000000000 --- a/vendor/k8s.io/kubernetes/pkg/api/endpoints/util.go +++ /dev/null @@ -1,235 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package endpoints - -import ( - "bytes" - "crypto/md5" - "encoding/hex" - "hash" - "sort" - - "k8s.io/apimachinery/pkg/types" - api "k8s.io/kubernetes/pkg/apis/core" - hashutil "k8s.io/kubernetes/pkg/util/hash" -) - -// RepackSubsets takes a slice of EndpointSubset objects, expands it to the full -// representation, and then repacks that into the canonical layout. This -// ensures that code which operates on these objects can rely on the common -// form for things like comparison. The result is a newly allocated slice. -func RepackSubsets(subsets []api.EndpointSubset) []api.EndpointSubset { - // First map each unique port definition to the sets of hosts that - // offer it. - allAddrs := map[addressKey]*api.EndpointAddress{} - portToAddrReadyMap := map[api.EndpointPort]addressSet{} - for i := range subsets { - if len(subsets[i].Ports) == 0 { - // Don't discard endpoints with no ports defined, use a sentinel. - mapAddressesByPort(&subsets[i], api.EndpointPort{Port: -1}, allAddrs, portToAddrReadyMap) - } else { - for _, port := range subsets[i].Ports { - mapAddressesByPort(&subsets[i], port, allAddrs, portToAddrReadyMap) - } - } - } - - // Next, map the sets of hosts to the sets of ports they offer. - // Go does not allow maps or slices as keys to maps, so we have - // to synthesize an artificial key and do a sort of 2-part - // associative entity. - type keyString string - keyToAddrReadyMap := map[keyString]addressSet{} - addrReadyMapKeyToPorts := map[keyString][]api.EndpointPort{} - for port, addrs := range portToAddrReadyMap { - key := keyString(hashAddresses(addrs)) - keyToAddrReadyMap[key] = addrs - if port.Port > 0 { // avoid sentinels - addrReadyMapKeyToPorts[key] = append(addrReadyMapKeyToPorts[key], port) - } else { - if _, found := addrReadyMapKeyToPorts[key]; !found { - // Force it to be present in the map - addrReadyMapKeyToPorts[key] = nil - } - } - } - - // Next, build the N-to-M association the API wants. - final := []api.EndpointSubset{} - for key, ports := range addrReadyMapKeyToPorts { - var readyAddrs, notReadyAddrs []api.EndpointAddress - for addr, ready := range keyToAddrReadyMap[key] { - if ready { - readyAddrs = append(readyAddrs, *addr) - } else { - notReadyAddrs = append(notReadyAddrs, *addr) - } - } - final = append(final, api.EndpointSubset{Addresses: readyAddrs, NotReadyAddresses: notReadyAddrs, Ports: ports}) - } - - // Finally, sort it. - return SortSubsets(final) -} - -// The sets of hosts must be de-duped, using IP+UID as the key. -type addressKey struct { - ip string - uid types.UID -} - -// mapAddressesByPort adds all ready and not-ready addresses into a map by a single port. -func mapAddressesByPort(subset *api.EndpointSubset, port api.EndpointPort, allAddrs map[addressKey]*api.EndpointAddress, portToAddrReadyMap map[api.EndpointPort]addressSet) { - for k := range subset.Addresses { - mapAddressByPort(&subset.Addresses[k], port, true, allAddrs, portToAddrReadyMap) - } - for k := range subset.NotReadyAddresses { - mapAddressByPort(&subset.NotReadyAddresses[k], port, false, allAddrs, portToAddrReadyMap) - } -} - -// mapAddressByPort adds one address into a map by port, registering the address with a unique pointer, and preserving -// any existing ready state. -func mapAddressByPort(addr *api.EndpointAddress, port api.EndpointPort, ready bool, allAddrs map[addressKey]*api.EndpointAddress, portToAddrReadyMap map[api.EndpointPort]addressSet) *api.EndpointAddress { - // use addressKey to distinguish between two endpoints that are identical addresses - // but may have come from different hosts, for attribution. - key := addressKey{ip: addr.IP} - if addr.TargetRef != nil { - key.uid = addr.TargetRef.UID - } - - // Accumulate the address. The full EndpointAddress structure is preserved for use when - // we rebuild the subsets so that the final TargetRef has all of the necessary data. - existingAddress := allAddrs[key] - if existingAddress == nil { - // Make a copy so we don't write to the - // input args of this function. - existingAddress = &api.EndpointAddress{} - *existingAddress = *addr - allAddrs[key] = existingAddress - } - - // Remember that this port maps to this address. - if _, found := portToAddrReadyMap[port]; !found { - portToAddrReadyMap[port] = addressSet{} - } - // if we have not yet recorded this port for this address, or if the previous - // state was ready, write the current ready state. not ready always trumps - // ready. - if wasReady, found := portToAddrReadyMap[port][existingAddress]; !found || wasReady { - portToAddrReadyMap[port][existingAddress] = ready - } - return existingAddress -} - -type addressSet map[*api.EndpointAddress]bool - -type addrReady struct { - addr *api.EndpointAddress - ready bool -} - -func hashAddresses(addrs addressSet) string { - // Flatten the list of addresses into a string so it can be used as a - // map key. Unfortunately, DeepHashObject is implemented in terms of - // spew, and spew does not handle non-primitive map keys well. So - // first we collapse it into a slice, sort the slice, then hash that. - slice := make([]addrReady, 0, len(addrs)) - for k, ready := range addrs { - slice = append(slice, addrReady{k, ready}) - } - sort.Sort(addrsReady(slice)) - hasher := md5.New() - hashutil.DeepHashObject(hasher, slice) - return hex.EncodeToString(hasher.Sum(nil)[0:]) -} - -func lessAddrReady(a, b addrReady) bool { - // ready is not significant to hashing since we can't have duplicate addresses - return LessEndpointAddress(a.addr, b.addr) -} - -type addrsReady []addrReady - -func (sl addrsReady) Len() int { return len(sl) } -func (sl addrsReady) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } -func (sl addrsReady) Less(i, j int) bool { - return lessAddrReady(sl[i], sl[j]) -} - -// LessEndpointAddress compares IP addresses lexicographically and returns true if first argument is lesser than second -func LessEndpointAddress(a, b *api.EndpointAddress) bool { - ipComparison := bytes.Compare([]byte(a.IP), []byte(b.IP)) - if ipComparison != 0 { - return ipComparison < 0 - } - if b.TargetRef == nil { - return false - } - if a.TargetRef == nil { - return true - } - return a.TargetRef.UID < b.TargetRef.UID -} - -// SortSubsets sorts an array of EndpointSubset objects in place. For ease of -// use it returns the input slice. -func SortSubsets(subsets []api.EndpointSubset) []api.EndpointSubset { - for i := range subsets { - ss := &subsets[i] - sort.Sort(addrsByIPAndUID(ss.Addresses)) - sort.Sort(addrsByIPAndUID(ss.NotReadyAddresses)) - sort.Sort(portsByHash(ss.Ports)) - } - sort.Sort(subsetsByHash(subsets)) - return subsets -} - -func hashObject(hasher hash.Hash, obj interface{}) []byte { - hashutil.DeepHashObject(hasher, obj) - return hasher.Sum(nil) -} - -type subsetsByHash []api.EndpointSubset - -func (sl subsetsByHash) Len() int { return len(sl) } -func (sl subsetsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } -func (sl subsetsByHash) Less(i, j int) bool { - hasher := md5.New() - h1 := hashObject(hasher, sl[i]) - h2 := hashObject(hasher, sl[j]) - return bytes.Compare(h1, h2) < 0 -} - -type addrsByIPAndUID []api.EndpointAddress - -func (sl addrsByIPAndUID) Len() int { return len(sl) } -func (sl addrsByIPAndUID) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } -func (sl addrsByIPAndUID) Less(i, j int) bool { - return LessEndpointAddress(&sl[i], &sl[j]) -} - -type portsByHash []api.EndpointPort - -func (sl portsByHash) Len() int { return len(sl) } -func (sl portsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } -func (sl portsByHash) Less(i, j int) bool { - hasher := md5.New() - h1 := hashObject(hasher, sl[i]) - h2 := hashObject(hasher, sl[j]) - return bytes.Compare(h1, h2) < 0 -} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/OWNERS b/vendor/k8s.io/kubernetes/pkg/apis/core/OWNERS index 61f00cee0c96..a689545f7bfe 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/OWNERS +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/OWNERS @@ -6,7 +6,6 @@ approvers: - smarterclayton - thockin - liggitt -# - bgrant0607 # manual escalations only reviewers: - thockin - lavalamp diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/types.go b/vendor/k8s.io/kubernetes/pkg/apis/core/types.go index 1af03e2990c1..0f777c799320 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/types.go @@ -5109,6 +5109,7 @@ type ComponentCondition struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ComponentStatus (and ComponentStatusList) holds the cluster validation info. +// Deprecated: This API is deprecated in v1.19+ type ComponentStatus struct { metav1.TypeMeta // +optional @@ -5121,6 +5122,7 @@ type ComponentStatus struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ComponentStatusList represents the list of component statuses +// Deprecated: This API is deprecated in v1.19+ type ComponentStatusList struct { metav1.TypeMeta // +optional diff --git a/vendor/k8s.io/kubernetes/pkg/apis/networking/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/apis/networking/validation/validation.go index 7508bd4851ff..b053d279e64f 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/networking/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/networking/validation/validation.go @@ -199,6 +199,11 @@ var ValidateIngressName = apimachineryvalidation.NameIsDNSSubdomain // IngressValidationOptions cover beta to GA transitions for HTTP PathType type IngressValidationOptions struct { + // AllowInvalidSecretName indicates whether spec.tls[*].secretName values that are not valid Secret names should be allowed + AllowInvalidSecretName bool + + // AllowInvalidWildcardHostRule indicates whether invalid rule values are allowed in rules with wildcard hostnames + AllowInvalidWildcardHostRule bool } // ValidateIngress validates Ingresses on create and update. @@ -212,7 +217,10 @@ func validateIngress(ingress *networking.Ingress, opts IngressValidationOptions, func ValidateIngressCreate(ingress *networking.Ingress, requestGV schema.GroupVersion) field.ErrorList { allErrs := field.ErrorList{} var opts IngressValidationOptions - opts = IngressValidationOptions{} + opts = IngressValidationOptions{ + AllowInvalidSecretName: allowInvalidSecretName(requestGV, nil), + AllowInvalidWildcardHostRule: allowInvalidWildcardHostRule(requestGV, nil), + } allErrs = append(allErrs, validateIngress(ingress, opts, requestGV)...) annotationVal, annotationIsSet := ingress.Annotations[annotationIngressClass] if annotationIsSet && ingress.Spec.IngressClassName != nil { @@ -226,26 +234,35 @@ func ValidateIngressCreate(ingress *networking.Ingress, requestGV schema.GroupVe func ValidateIngressUpdate(ingress, oldIngress *networking.Ingress, requestGV schema.GroupVersion) field.ErrorList { allErrs := apivalidation.ValidateObjectMetaUpdate(&ingress.ObjectMeta, &oldIngress.ObjectMeta, field.NewPath("metadata")) var opts IngressValidationOptions - opts = IngressValidationOptions{} + opts = IngressValidationOptions{ + AllowInvalidSecretName: allowInvalidSecretName(requestGV, oldIngress), + AllowInvalidWildcardHostRule: allowInvalidWildcardHostRule(requestGV, oldIngress), + } allErrs = append(allErrs, validateIngress(ingress, opts, requestGV)...) return allErrs } -func validateIngressTLS(spec *networking.IngressSpec, fldPath *field.Path) field.ErrorList { +func validateIngressTLS(spec *networking.IngressSpec, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} // TODO: Perform a more thorough validation of spec.TLS.Hosts that takes // the wildcard spec from RFC 6125 into account. - for _, itls := range spec.TLS { + for tlsIndex, itls := range spec.TLS { for i, host := range itls.Hosts { if strings.Contains(host, "*") { for _, msg := range validation.IsWildcardDNS1123Subdomain(host) { - allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("hosts"), host, msg)) + allErrs = append(allErrs, field.Invalid(fldPath.Index(tlsIndex).Child("hosts").Index(i), host, msg)) } continue } for _, msg := range validation.IsDNS1123Subdomain(host) { - allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("hosts"), host, msg)) + allErrs = append(allErrs, field.Invalid(fldPath.Index(tlsIndex).Child("hosts").Index(i), host, msg)) + } + } + + if !opts.AllowInvalidSecretName { + for _, msg := range validateTLSSecretName(itls.SecretName) { + allErrs = append(allErrs, field.Invalid(fldPath.Index(tlsIndex).Child("secretName"), itls.SecretName, msg)) } } } @@ -278,7 +295,7 @@ func ValidateIngressSpec(spec *networking.IngressSpec, fldPath *field.Path, opts allErrs = append(allErrs, validateIngressRules(spec.Rules, fldPath.Child("rules"), opts, requestGV)...) } if len(spec.TLS) > 0 { - allErrs = append(allErrs, validateIngressTLS(spec, fldPath.Child("tls"))...) + allErrs = append(allErrs, validateIngressTLS(spec, fldPath.Child("tls"), opts)...) } if spec.IngressClassName != nil { for _, msg := range ValidateIngressClassName(*spec.IngressClassName, false) { @@ -301,6 +318,7 @@ func validateIngressRules(ingressRules []networking.IngressRule, fldPath *field. return append(allErrs, field.Required(fldPath, "")) } for i, ih := range ingressRules { + wildcardHost := false if len(ih.Host) > 0 { if isIP := (net.ParseIP(ih.Host) != nil); isIP { allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, "must be a DNS name, not an IP address")) @@ -311,13 +329,17 @@ func validateIngressRules(ingressRules []networking.IngressRule, fldPath *field. for _, msg := range validation.IsWildcardDNS1123Subdomain(ih.Host) { allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, msg)) } - continue - } - for _, msg := range validation.IsDNS1123Subdomain(ih.Host) { - allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, msg)) + wildcardHost = true + } else { + for _, msg := range validation.IsDNS1123Subdomain(ih.Host) { + allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, msg)) + } } } - allErrs = append(allErrs, validateIngressRuleValue(&ih.IngressRuleValue, fldPath.Index(0), opts, requestGV)...) + + if !wildcardHost || !opts.AllowInvalidWildcardHostRule { + allErrs = append(allErrs, validateIngressRuleValue(&ih.IngressRuleValue, fldPath.Index(i), opts, requestGV)...) + } } return allErrs } @@ -523,3 +545,42 @@ func validateIngressTypedLocalObjectReference(params *api.TypedLocalObjectRefere return allErrs } + +func allowInvalidSecretName(gv schema.GroupVersion, oldIngress *networking.Ingress) bool { + if gv == networkingv1beta1.SchemeGroupVersion || gv == extensionsv1beta1.SchemeGroupVersion { + // backwards compatibility with released API versions that allowed invalid names + return true + } + if oldIngress != nil { + for _, tls := range oldIngress.Spec.TLS { + if len(validateTLSSecretName(tls.SecretName)) > 0 { + // backwards compatibility with existing persisted object + return true + } + } + } + return false +} + +func validateTLSSecretName(name string) []string { + if len(name) == 0 { + return nil + } + return apivalidation.ValidateSecretName(name, false) +} + +func allowInvalidWildcardHostRule(gv schema.GroupVersion, oldIngress *networking.Ingress) bool { + if gv == networkingv1beta1.SchemeGroupVersion || gv == extensionsv1beta1.SchemeGroupVersion { + // backwards compatibility with released API versions that allowed invalid rules + return true + } + if oldIngress != nil { + for _, rule := range oldIngress.Spec.Rules { + if strings.Contains(rule.Host, "*") && len(validateIngressRuleValue(&rule.IngressRuleValue, nil, IngressValidationOptions{}, gv)) > 0 { + // backwards compatibility with existing invalid data + return true + } + } + } + return false +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/OWNERS b/vendor/k8s.io/kubernetes/pkg/controller/OWNERS index 6a0dca593a5b..a4f3bf7ea3a6 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/OWNERS +++ b/vendor/k8s.io/kubernetes/pkg/controller/OWNERS @@ -5,6 +5,7 @@ approvers: - derekwaynecarr - mikedanese - janetkuo +- cheftako - sig-apps-approvers reviewers: - deads2k diff --git a/vendor/k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler/BUILD b/vendor/k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler/BUILD index abf160f7aa91..6949d3866eff 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler/BUILD @@ -42,6 +42,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler/taint_manager.go b/vendor/k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler/taint_manager.go index 60223452dfab..8e38578a1a2a 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler/taint_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler/taint_manager.go @@ -358,7 +358,8 @@ func (tc *NoExecuteTaintManager) processPodOnNode( minTolerationTime := getMinTolerationTime(usedTolerations) // getMinTolerationTime returns negative value to denote infinite toleration. if minTolerationTime < 0 { - klog.V(4).Infof("New tolerations for %v tolerate forever. Scheduled deletion won't be cancelled if already scheduled.", podNamespacedName.String()) + klog.V(4).Infof("Current tolerations for %v tolerate forever, cancelling any scheduled deletion.", podNamespacedName.String()) + tc.cancelWorkWithEvent(podNamespacedName) return } diff --git a/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/BUILD b/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/BUILD index ba9ec88167b8..85485c6e26b3 100644 --- a/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/BUILD @@ -11,6 +11,7 @@ go_library( srcs = [ "azure_acr_helper.go", "azure_credentials.go", + "doc.go", ], importpath = "k8s.io/kubernetes/pkg/credentialprovider/azure", deps = [ diff --git a/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/azure_acr_helper.go b/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/azure_acr_helper.go index 12a2ad3f3b6b..347b1658a918 100644 --- a/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/azure_acr_helper.go +++ b/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/azure_acr_helper.go @@ -1,3 +1,5 @@ +// +build !providerless + /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/azure_credentials.go b/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/azure_credentials.go index 74670a3d1f67..f10288825001 100644 --- a/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/azure_credentials.go +++ b/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/azure_credentials.go @@ -1,3 +1,5 @@ +// +build !providerless + /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/doc.go b/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/doc.go new file mode 100644 index 000000000000..b61f8a238db3 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/credentialprovider/azure/doc.go @@ -0,0 +1,17 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package azure diff --git a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go index 2069278d1b46..f36ae65c0ccd 100644 --- a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go +++ b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go @@ -639,6 +639,12 @@ const ( // // Allows kube-proxy to create DSR loadbalancers for Windows WinDSR featuregate.Feature = "WinDSR" + + // owner: @RenaudWasTaken @dashpole + // alpha: v1.19 + // + // Disables Accelerator Metrics Collected by Kubelet + DisableAcceleratorUsageMetrics featuregate.Feature = "DisableAcceleratorUsageMetrics" ) func init() { @@ -737,6 +743,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS SetHostnameAsFQDN: {Default: false, PreRelease: featuregate.Alpha}, WinOverlay: {Default: false, PreRelease: featuregate.Alpha}, WinDSR: {Default: false, PreRelease: featuregate.Alpha}, + DisableAcceleratorUsageMetrics: {Default: false, PreRelease: featuregate.Alpha}, // inherited features from generic apiserver, relisted here to get a conflict if it is changed // unintentionally on either side: diff --git a/vendor/k8s.io/kubernetes/pkg/generated/openapi/.gitignore b/vendor/k8s.io/kubernetes/pkg/generated/openapi/.gitignore new file mode 100644 index 000000000000..94138bddbae8 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/generated/openapi/.gitignore @@ -0,0 +1,3 @@ +# Ensure that openapi definitions are not ignored to ensure that +# openshift/origin can vendor them. +!zz_generated.openapi.go diff --git a/vendor/k8s.io/kubernetes/pkg/generated/openapi/zz_generated.openapi.go b/vendor/k8s.io/kubernetes/pkg/generated/openapi/zz_generated.openapi.go index c253d1fc213f..1390fc99b64c 100644 --- a/vendor/k8s.io/kubernetes/pkg/generated/openapi/zz_generated.openapi.go +++ b/vendor/k8s.io/kubernetes/pkg/generated/openapi/zz_generated.openapi.go @@ -12731,7 +12731,7 @@ func schema_k8sio_api_core_v1_ComponentStatus(ref common.ReferenceCallback) comm return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "ComponentStatus (and ComponentStatusList) holds the cluster validation info.", + Description: "ComponentStatus (and ComponentStatusList) holds the cluster validation info. Deprecated: This API is deprecated in v1.19+", Type: []string{"object"}, Properties: map[string]spec.Schema{ "kind": { @@ -12785,7 +12785,7 @@ func schema_k8sio_api_core_v1_ComponentStatusList(ref common.ReferenceCallback) return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "Status of all the conditions for the component as a list of ComponentStatus objects.", + Description: "Status of all the conditions for the component as a list of ComponentStatus objects. Deprecated: This API is deprecated in v1.19+", Type: []string{"object"}, Properties: map[string]spec.Schema{ "kind": { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/BUILD index e1f24fffc6fe..7efbf4a69274 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/BUILD @@ -29,6 +29,7 @@ go_library( "reason_cache.go", "runonce.go", "runtime.go", + "time_cache.go", "util.go", "volume_host.go", ], @@ -179,6 +180,7 @@ go_test( "pod_workers_test.go", "reason_cache_test.go", "runonce_test.go", + "time_cache_test.go", ], embed = [":go_default_library"], deps = [ @@ -251,6 +253,7 @@ go_test( "//staging/src/k8s.io/client-go/util/testing:go_default_library", "//staging/src/k8s.io/component-base/featuregate/testing:go_default_library", "//staging/src/k8s.io/component-base/version:go_default_library", + "//vendor/github.com/golang/groupcache/lru:go_default_library", "//vendor/github.com/google/cadvisor/info/v1:go_default_library", "//vendor/github.com/google/cadvisor/info/v2:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/BUILD index b1fd5530a27a..646569dc33b6 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/BUILD @@ -45,6 +45,11 @@ go_library( "//staging/src/k8s.io/cri-api/pkg/apis:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/kubelet/cadvisor:go_default_library", + "//staging/src/k8s.io/client-go/tools/record:go_default_library", + "//vendor/k8s.io/utils/mount:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/api/v1/resource:go_default_library", "//pkg/apis/core/v1/helper:go_default_library", @@ -92,11 +97,21 @@ go_library( "//staging/src/k8s.io/client-go/tools/record:go_default_library", "//vendor/k8s.io/utils/mount:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/kubelet/cadvisor:go_default_library", + "//staging/src/k8s.io/client-go/tools/record:go_default_library", + "//vendor/k8s.io/utils/mount:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//pkg/kubelet/cadvisor:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library", "//vendor/k8s.io/utils/mount:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/kubelet/cadvisor:go_default_library", + "//staging/src/k8s.io/client-go/tools/record:go_default_library", + "//vendor/k8s.io/utils/mount:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/api/v1/resource:go_default_library", "//pkg/apis/core/v1/helper:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go index adbac8d6a1af..ad3f876ab89e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go @@ -338,15 +338,16 @@ func (p *staticPolicy) GetTopologyHints(s state.State, pod *v1.Pod, container *v } klog.Infof("[cpumanager] Regenerating TopologyHints for CPUs already allocated to (pod %v, container %v)", string(pod.UID), container.Name) return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): p.generateCPUTopologyHints(allocated, requested), + string(v1.ResourceCPU): p.generateCPUTopologyHints(allocated, cpuset.CPUSet{}, requested), } } // Get a list of available CPUs. available := p.assignableCPUs(s) + reusable := p.cpusToReuse[string(pod.UID)] // Generate hints. - cpuHints := p.generateCPUTopologyHints(available, requested) + cpuHints := p.generateCPUTopologyHints(available, reusable, requested) klog.Infof("[cpumanager] TopologyHints generated for pod '%v', container '%v': %v", pod.Name, container.Name, cpuHints) return map[string][]topologymanager.TopologyHint{ @@ -360,7 +361,7 @@ func (p *staticPolicy) GetTopologyHints(s state.State, pod *v1.Pod, container *v // It follows the convention of marking all hints that have the same number of // bits set as the narrowest matching NUMANodeAffinity with 'Preferred: true', and // marking all others with 'Preferred: false'. -func (p *staticPolicy) generateCPUTopologyHints(availableCPUs cpuset.CPUSet, request int) []topologymanager.TopologyHint { +func (p *staticPolicy) generateCPUTopologyHints(availableCPUs cpuset.CPUSet, reusableCPUs cpuset.CPUSet, request int) []topologymanager.TopologyHint { // Initialize minAffinitySize to include all NUMA Nodes. minAffinitySize := p.topology.CPUDetails.NUMANodes().Size() // Initialize minSocketsOnMinAffinity to include all Sockets. @@ -380,16 +381,25 @@ func (p *staticPolicy) generateCPUTopologyHints(availableCPUs cpuset.CPUSet, req } } - // Then check to see if we have enough CPUs available on the current - // socket bitmask to satisfy the CPU request. + // Then check to see if all of the reusable CPUs are part of the bitmask. numMatching := 0 + for _, c := range reusableCPUs.ToSlice() { + // Disregard this mask if its NUMANode isn't part of it. + if !mask.IsSet(p.topology.CPUDetails[c].NUMANodeID) { + return + } + numMatching++ + } + + // Finally, check to see if enough available CPUs remain on the current + // NUMA node combination to satisfy the CPU request. for _, c := range availableCPUs.ToSlice() { if mask.IsSet(p.topology.CPUDetails[c].NUMANodeID) { numMatching++ } } - // If we don't, then move onto the next combination. + // If they don't, then move onto the next combination. if numMatching < request { return } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go index a423c2d35920..ab5b0859b3dc 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go @@ -20,6 +20,7 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" + pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" ) @@ -57,21 +58,22 @@ func (m *ManagerImpl) GetTopologyHints(pod *v1.Pod, container *v1.Container) map continue } klog.Infof("[devicemanager] Regenerating TopologyHints for resource '%v' already allocated to (pod %v, container %v)", resource, string(pod.UID), container.Name) - deviceHints[resource] = m.generateDeviceTopologyHints(resource, allocated, requested) + deviceHints[resource] = m.generateDeviceTopologyHints(resource, allocated, sets.String{}, requested) continue } // Get the list of available devices, for which TopologyHints should be generated. available := m.getAvailableDevices(resource) - if available.Len() < requested { - klog.Errorf("[devicemanager] Unable to generate topology hints: requested number of devices unavailable for '%s': requested: %d, available: %d", resource, requested, available.Len()) + reusable := m.devicesToReuse[string(pod.UID)][resource] + if available.Union(reusable).Len() < requested { + klog.Errorf("[devicemanager] Unable to generate topology hints: requested number of devices unavailable for '%s': requested: %d, available: %d", resource, requested, available.Union(reusable).Len()) deviceHints[resource] = []topologymanager.TopologyHint{} continue } // Generate TopologyHints for this resource given the current // request size and the list of available devices. - deviceHints[resource] = m.generateDeviceTopologyHints(resource, available, requested) + deviceHints[resource] = m.generateDeviceTopologyHints(resource, available, reusable, requested) } } @@ -93,7 +95,7 @@ func (m *ManagerImpl) getAvailableDevices(resource string) sets.String { return m.healthyDevices[resource].Difference(m.allocatedDevices[resource]) } -func (m *ManagerImpl) generateDeviceTopologyHints(resource string, devices sets.String, request int) []topologymanager.TopologyHint { +func (m *ManagerImpl) generateDeviceTopologyHints(resource string, available sets.String, reusable sets.String, request int) []topologymanager.TopologyHint { // Initialize minAffinitySize to include all NUMA Nodes minAffinitySize := len(m.numaNodes) @@ -103,36 +105,37 @@ func (m *ManagerImpl) generateDeviceTopologyHints(resource string, devices sets. // First, update minAffinitySize for the current request size. devicesInMask := 0 for _, device := range m.allDevices[resource] { - if device.Topology == nil { - continue - } - for _, node := range device.Topology.Nodes { - if mask.IsSet(int(node.ID)) { - devicesInMask++ - break - } + if mask.AnySet(m.getNUMANodeIds(device.Topology)) { + devicesInMask++ } } if devicesInMask >= request && mask.Count() < minAffinitySize { minAffinitySize = mask.Count() } - // Then check to see if we have enough devices available on the current - // NUMA Node combination to satisfy the device request. + // Then check to see if all of the reusable devices are part of the bitmask. numMatching := 0 - for d := range devices { + for d := range reusable { + // Skip the device if it doesn't specify any topology info. if m.allDevices[resource][d].Topology == nil { continue } - for _, node := range m.allDevices[resource][d].Topology.Nodes { - if mask.IsSet(int(node.ID)) { - numMatching++ - break - } + // Otherwise disregard this mask if its NUMANode isn't part of it. + if !mask.AnySet(m.getNUMANodeIds(m.allDevices[resource][d].Topology)) { + return } + numMatching++ } - // If we don't, then move onto the next combination. + // Finally, check to see if enough available devices remain on the + // current NUMA node combination to satisfy the device request. + for d := range available { + if mask.AnySet(m.getNUMANodeIds(m.allDevices[resource][d].Topology)) { + numMatching++ + } + } + + // If they don't, then move onto the next combination. if numMatching < request { return } @@ -158,3 +161,14 @@ func (m *ManagerImpl) generateDeviceTopologyHints(resource string, devices sets. return hints } + +func (m *ManagerImpl) getNUMANodeIds(topology *pluginapi.TopologyInfo) []int { + if topology == nil { + return nil + } + var ids []int + for _, n := range topology.Nodes { + ids = append(ids, int(n.ID)) + } + return ids +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask.go index 468f94f951ae..fb2043e01823 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask.go @@ -33,6 +33,7 @@ type BitMask interface { IsEqual(mask BitMask) bool IsEmpty() bool IsSet(bit int) bool + AnySet(bits []int) bool IsNarrowerThan(mask BitMask) bool String() string Count() int @@ -120,6 +121,16 @@ func (s *bitMask) IsSet(bit int) bool { return (*s & (1 << uint64(bit))) > 0 } +// AnySet checks bit in mask to see if any provided bit is set to one +func (s *bitMask) AnySet(bits []int) bool { + for _, b := range bits { + if s.IsSet(b) { + return true + } + } + return false +} + // IsEqual checks if masks are equal func (s *bitMask) IsEqual(mask BitMask) bool { return *s == *mask.(*bitMask) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go index bd27ae9f0798..dae825b957bd 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go @@ -38,6 +38,9 @@ type OSInterface interface { Pipe() (r *os.File, w *os.File, err error) ReadDir(dirname string) ([]os.FileInfo, error) Glob(pattern string) ([]string, error) + Open(name string) (*os.File, error) + OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) + Rename(oldpath, newpath string) error } // RealOS is used to dispatch the real system level operations. @@ -105,3 +108,18 @@ func (RealOS) ReadDir(dirname string) ([]os.FileInfo, error) { func (RealOS) Glob(pattern string) ([]string, error) { return filepath.Glob(pattern) } + +// Open will call os.Open to return the file. +func (RealOS) Open(name string) (*os.File, error) { + return os.Open(name) +} + +// OpenFile will call os.OpenFile to return the file. +func (RealOS) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) { + return os.OpenFile(name, flag, perm) +} + +// Rename will call os.Rename to rename a file. +func (RealOS) Rename(oldpath, newpath string) error { + return os.Rename(oldpath, newpath) +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/os.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/os.go index ee8d255b0873..16d344ba06dd 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/os.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/os.go @@ -30,6 +30,7 @@ type FakeOS struct { ReadDirFn func(string) ([]os.FileInfo, error) MkdirAllFn func(string, os.FileMode) error SymlinkFn func(string, string) error + GlobFn func(string, string) bool HostName string Removes []string Files map[string][]*os.FileInfo @@ -78,8 +79,12 @@ func (f *FakeOS) RemoveAll(path string) error { return nil } -// Create is a fake call that returns nil. -func (FakeOS) Create(path string) (*os.File, error) { +// Create is a fake call that creates a virtual file and returns nil. +func (f *FakeOS) Create(path string) (*os.File, error) { + if f.Files == nil { + f.Files = make(map[string][]*os.FileInfo) + } + f.Files[path] = []*os.FileInfo{} return nil, nil } @@ -111,7 +116,31 @@ func (f *FakeOS) ReadDir(dirname string) ([]os.FileInfo, error) { return nil, nil } -// Glob is a fake call that returns nil. +// Glob is a fake call that returns list of virtual files matching a pattern. func (f *FakeOS) Glob(pattern string) ([]string, error) { + if f.GlobFn != nil { + var res []string + for k := range f.Files { + if f.GlobFn(pattern, k) { + res = append(res, k) + } + } + return res, nil + } + return nil, nil +} + +// Open is a fake call that returns nil. +func (FakeOS) Open(name string) (*os.File, error) { return nil, nil } + +// OpenFile is a fake call that return nil. +func (FakeOS) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) { + return nil, nil +} + +// Rename is a fake call that return nil. +func (FakeOS) Rename(oldpath, newpath string) error { + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/cm/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/cm/BUILD index 3392465c75f3..880288320952 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/cm/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/cm/BUILD @@ -15,6 +15,9 @@ go_library( ], importpath = "k8s.io/kubernetes/pkg/kubelet/dockershim/cm", deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/kubelet/dockershim/libdocker:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/kubelet/cm:go_default_library", "//pkg/kubelet/dockershim/libdocker:go_default_library", @@ -34,9 +37,15 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//pkg/kubelet/dockershim/libdocker:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/kubelet/dockershim/libdocker:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//pkg/kubelet/dockershim/libdocker:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/kubelet/dockershim/libdocker:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/kubelet/cm:go_default_library", "//pkg/kubelet/dockershim/libdocker:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/network/kubenet/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/network/kubenet/BUILD index 2c8378c7d991..6597874820e4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/network/kubenet/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/network/kubenet/BUILD @@ -15,6 +15,11 @@ go_library( ], importpath = "k8s.io/kubernetes/pkg/kubelet/dockershim/network/kubenet", deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/kubelet/apis/config:go_default_library", + "//pkg/kubelet/container:go_default_library", + "//pkg/kubelet/dockershim/network:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/features:go_default_library", "//pkg/kubelet/apis/config:go_default_library", @@ -53,11 +58,21 @@ go_library( "//pkg/kubelet/container:go_default_library", "//pkg/kubelet/dockershim/network:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/kubelet/apis/config:go_default_library", + "//pkg/kubelet/container:go_default_library", + "//pkg/kubelet/dockershim/network:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//pkg/kubelet/apis/config:go_default_library", "//pkg/kubelet/container:go_default_library", "//pkg/kubelet/dockershim/network:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/kubelet/apis/config:go_default_library", + "//pkg/kubelet/container:go_default_library", + "//pkg/kubelet/dockershim/network:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/features:go_default_library", "//pkg/kubelet/apis/config:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go index 2252567abbbc..81f4d322ed8e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go @@ -525,6 +525,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, experimentalHostUserNamespaceDefaulting: utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalHostUserNamespaceDefaultingGate), keepTerminatedPodVolumes: keepTerminatedPodVolumes, nodeStatusMaxImages: nodeStatusMaxImages, + lastContainerStartedTime: newTimeCache(), } if klet.cloud != nil { @@ -560,7 +561,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, if err != nil { return nil, err } - klet.machineInfo = machineInfo + klet.setCachedMachineInfo(machineInfo) imageBackOff := flowcontrol.NewBackOff(backOffPeriod, MaxContainerBackOff) @@ -584,6 +585,22 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, klet.runtimeClassManager = runtimeclass.NewManager(kubeDeps.KubeClient) } + if containerRuntime == kubetypes.RemoteContainerRuntime && utilfeature.DefaultFeatureGate.Enabled(features.CRIContainerLogRotation) { + // setup containerLogManager for CRI container runtime + containerLogManager, err := logs.NewContainerLogManager( + klet.runtimeService, + kubeDeps.OSInterface, + kubeCfg.ContainerLogMaxSize, + int(kubeCfg.ContainerLogMaxFiles), + ) + if err != nil { + return nil, fmt.Errorf("failed to initialize container log manager: %v", err) + } + klet.containerLogManager = containerLogManager + } else { + klet.containerLogManager = logs.NewStubContainerLogManager() + } + runtime, err := kuberuntime.NewKubeGenericRuntimeManager( kubecontainer.FilterEventRecorder(kubeDeps.Recorder), klet.livenessManager, @@ -604,6 +621,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps.RemoteImageService, kubeDeps.ContainerManager.InternalContainerLifecycle(), kubeDeps.dockerLegacyService, + klet.containerLogManager, klet.runtimeClassManager, ) if err != nil { @@ -661,21 +679,6 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, } klet.imageManager = imageManager - if containerRuntime == kubetypes.RemoteContainerRuntime && utilfeature.DefaultFeatureGate.Enabled(features.CRIContainerLogRotation) { - // setup containerLogManager for CRI container runtime - containerLogManager, err := logs.NewContainerLogManager( - klet.runtimeService, - kubeCfg.ContainerLogMaxSize, - int(kubeCfg.ContainerLogMaxFiles), - ) - if err != nil { - return nil, fmt.Errorf("failed to initialize container log manager: %v", err) - } - klet.containerLogManager = containerLogManager - } else { - klet.containerLogManager = logs.NewStubContainerLogManager() - } - if kubeCfg.ServerTLSBootstrap && kubeDeps.TLSOptions != nil && utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletServerCertificate) { klet.serverCertificateManager, err = kubeletcertificate.NewKubeletServerCertificateManager(klet.kubeClient, kubeCfg, klet.nodeName, klet.getLastObservedNodeAddresses, certDirectory) if err != nil { @@ -910,7 +913,8 @@ type Kubelet struct { configMapManager configmap.Manager // Cached MachineInfo returned by cadvisor. - machineInfo *cadvisorapi.MachineInfo + machineInfoLock sync.RWMutex + machineInfo *cadvisorapi.MachineInfo // Handles certificate rotations. serverCertificateManager certificate.Manager @@ -975,6 +979,9 @@ type Kubelet struct { // lastStatusReportTime is the time when node status was last reported. lastStatusReportTime time.Time + // lastContainerStartedTime is the time of the last ContainerStarted event observed per pod + lastContainerStartedTime *timeCache + // syncNodeStatusMux is a lock on updating the node status, because this path is not thread-safe. // This lock is used by Kubelet.syncNodeStatus function and shouldn't be used anywhere else. syncNodeStatusMux sync.Mutex @@ -1662,6 +1669,13 @@ func (kl *Kubelet) deletePod(pod *v1.Pod) error { } kl.podWorkers.ForgetWorker(pod.UID) + // make sure our runtimeCache is at least as fresh as the last container started event we observed. + // this ensures we correctly send graceful deletion signals to all containers we've reported started. + if lastContainerStarted, ok := kl.lastContainerStartedTime.Get(pod.UID); ok { + if err := kl.runtimeCache.ForceUpdateIfOlder(lastContainerStarted); err != nil { + return fmt.Errorf("error updating containers: %v", err) + } + } // Runtime cache may not have been updated to with the pod, but it's okay // because the periodic cleanup routine will attempt to delete again later. runningPods, err := kl.runtimeCache.GetPods() @@ -1846,6 +1860,12 @@ func (kl *Kubelet) syncLoopIteration(configCh <-chan kubetypes.PodUpdate, handle kl.sourcesReady.AddSource(u.Source) case e := <-plegCh: + if e.Type == pleg.ContainerStarted { + // record the most recent time we observed a container start for this pod. + // this lets us selectively invalidate the runtimeCache when processing a delete for this pod + // to make sure we don't miss handling graceful termination for containers we reported as having started. + kl.lastContainerStartedTime.Add(e.ID, time.Now()) + } if isSyncPodWorthy(e) { // PLEG event for a pod; sync it. if pod, ok := kl.podManager.GetPodByUID(e.ID); ok { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go index 76e8d08bfc52..aed08db4c2fb 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go @@ -382,5 +382,13 @@ func (kl *Kubelet) GetVersionInfo() (*cadvisorapiv1.VersionInfo, error) { // GetCachedMachineInfo assumes that the machine info can't change without a reboot func (kl *Kubelet) GetCachedMachineInfo() (*cadvisorapiv1.MachineInfo, error) { + kl.machineInfoLock.RLock() + defer kl.machineInfoLock.RUnlock() return kl.machineInfo, nil } + +func (kl *Kubelet) setCachedMachineInfo(info *cadvisorapiv1.MachineInfo) { + kl.machineInfoLock.Lock() + defer kl.machineInfoLock.Unlock() + kl.machineInfo = info +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/BUILD index f22fa2f23b9b..19306019ceb1 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/BUILD @@ -41,6 +41,7 @@ go_library( "//pkg/kubelet/images:go_default_library", "//pkg/kubelet/kuberuntime/logs:go_default_library", "//pkg/kubelet/lifecycle:go_default_library", + "//pkg/kubelet/logs:go_default_library", "//pkg/kubelet/metrics:go_default_library", "//pkg/kubelet/prober/results:go_default_library", "//pkg/kubelet/runtimeclass:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go index df9fc0284160..a7190df20876 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go @@ -32,6 +32,7 @@ import ( kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/lifecycle" + "k8s.io/kubernetes/pkg/kubelet/logs" proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results" ) @@ -73,6 +74,10 @@ func (f *fakePodStateProvider) IsPodTerminated(uid types.UID) bool { func newFakeKubeRuntimeManager(runtimeService internalapi.RuntimeService, imageService internalapi.ImageManagerService, machineInfo *cadvisorapi.MachineInfo, osInterface kubecontainer.OSInterface, runtimeHelper kubecontainer.RuntimeHelper, keyring credentialprovider.DockerKeyring) (*kubeGenericRuntimeManager, error) { recorder := &record.FakeRecorder{} + logManager, err := logs.NewContainerLogManager(runtimeService, osInterface, "1", 2) + if err != nil { + return nil, err + } kubeRuntimeManager := &kubeGenericRuntimeManager{ recorder: recorder, cpuCFSQuota: false, @@ -88,6 +93,7 @@ func newFakeKubeRuntimeManager(runtimeService internalapi.RuntimeService, imageS seccompProfileRoot: fakeSeccompProfileRoot, internalLifecycle: cm.NewFakeInternalContainerLifecycle(), logReduction: logreduction.NewLogReduction(identicalErrorDelay), + logManager: logManager, } typedVersion, err := runtimeService.Version(kubeRuntimeAPIVersion) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go index ec8d9fac03ff..af361122c35f 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -855,19 +855,19 @@ func (m *kubeGenericRuntimeManager) removeContainer(containerID string) error { // removeContainerLog removes the container log. func (m *kubeGenericRuntimeManager) removeContainerLog(containerID string) error { - // Remove the container log. + // Use log manager to remove rotated logs. + err := m.logManager.Clean(containerID) + if err != nil { + return err + } + status, err := m.runtimeService.ContainerStatus(containerID) if err != nil { return fmt.Errorf("failed to get container status %q: %v", containerID, err) } - labeledInfo := getContainerInfoFromLabels(status.Labels) - path := status.GetLogPath() - if err := m.osInterface.Remove(path); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to remove container %q log %q: %v", containerID, path, err) - } - // Remove the legacy container log symlink. // TODO(random-liu): Remove this after cluster logging supports CRI container log path. + labeledInfo := getContainerInfoFromLabels(status.Labels) legacySymlink := legacyLogSymlink(containerID, labeledInfo.ContainerName, labeledInfo.PodName, labeledInfo.PodNamespace) if err := m.osInterface.Remove(legacySymlink); err != nil && !os.IsNotExist(err) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go index eebba49bbbe2..67d121d7321e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -46,6 +46,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/lifecycle" + "k8s.io/kubernetes/pkg/kubelet/logs" proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results" "k8s.io/kubernetes/pkg/kubelet/runtimeclass" "k8s.io/kubernetes/pkg/kubelet/types" @@ -127,6 +128,9 @@ type kubeGenericRuntimeManager struct { // A shim to legacy functions for backward compatibility. legacyLogProvider LegacyLogProvider + // Manage container logs. + logManager logs.ContainerLogManager + // Manage RuntimeClass resources. runtimeClassManager *runtimeclass.Manager @@ -168,6 +172,7 @@ func NewKubeGenericRuntimeManager( imageService internalapi.ImageManagerService, internalLifecycle cm.InternalContainerLifecycle, legacyLogProvider LegacyLogProvider, + logManager logs.ContainerLogManager, runtimeClassManager *runtimeclass.Manager, ) (KubeGenericRuntime, error) { kubeRuntimeManager := &kubeGenericRuntimeManager{ @@ -185,6 +190,7 @@ func NewKubeGenericRuntimeManager( keyring: credentialprovider.NewDockerKeyring(), internalLifecycle: internalLifecycle, legacyLogProvider: legacyLogProvider, + logManager: logManager, runtimeClassManager: runtimeClassManager, logReduction: logreduction.NewLogReduction(identicalErrorDelay), } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/logs/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/logs/BUILD index 7ef5310df09d..0b7a608c0508 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/logs/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/logs/BUILD @@ -9,6 +9,7 @@ go_library( importpath = "k8s.io/kubernetes/pkg/kubelet/logs", visibility = ["//visibility:public"], deps = [ + "//pkg/kubelet/container:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", @@ -23,6 +24,7 @@ go_test( srcs = ["container_log_manager_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/kubelet/container:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library", "//staging/src/k8s.io/cri-api/pkg/apis/testing:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/logs/container_log_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/logs/container_log_manager.go index 502f3b622ccf..56e4f31169d8 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/logs/container_log_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/logs/container_log_manager.go @@ -24,6 +24,7 @@ import ( "path/filepath" "sort" "strings" + "sync" "time" "k8s.io/klog/v2" @@ -33,6 +34,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" internalapi "k8s.io/cri-api/pkg/apis" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) const ( @@ -55,6 +57,8 @@ type ContainerLogManager interface { // TODO(random-liu): Add RotateLogs function and call it under disk pressure. // Start container log manager. Start() + // Clean removes all logs of specified container. + Clean(containerID string) error } // LogRotatePolicy is a policy for container log rotation. The policy applies to all @@ -142,12 +146,14 @@ func parseMaxSize(size string) (int64, error) { type containerLogManager struct { runtimeService internalapi.RuntimeService + osInterface kubecontainer.OSInterface policy LogRotatePolicy clock clock.Clock + mutex sync.Mutex } // NewContainerLogManager creates a new container log manager. -func NewContainerLogManager(runtimeService internalapi.RuntimeService, maxSize string, maxFiles int) (ContainerLogManager, error) { +func NewContainerLogManager(runtimeService internalapi.RuntimeService, osInterface kubecontainer.OSInterface, maxSize string, maxFiles int) (ContainerLogManager, error) { if maxFiles <= 1 { return nil, fmt.Errorf("invalid MaxFiles %d, must be > 1", maxFiles) } @@ -157,12 +163,14 @@ func NewContainerLogManager(runtimeService internalapi.RuntimeService, maxSize s } // policy LogRotatePolicy return &containerLogManager{ + osInterface: osInterface, runtimeService: runtimeService, policy: LogRotatePolicy{ MaxSize: parsedMaxSize, MaxFiles: maxFiles, }, clock: clock.RealClock{}, + mutex: sync.Mutex{}, }, nil } @@ -176,7 +184,32 @@ func (c *containerLogManager) Start() { }, logMonitorPeriod) } +// Clean removes all logs of specified container (including rotated one). +func (c *containerLogManager) Clean(containerID string) error { + c.mutex.Lock() + defer c.mutex.Unlock() + status, err := c.runtimeService.ContainerStatus(containerID) + if err != nil { + return fmt.Errorf("failed to get container status %q: %v", containerID, err) + } + pattern := fmt.Sprintf("%s*", status.GetLogPath()) + logs, err := c.osInterface.Glob(pattern) + if err != nil { + return fmt.Errorf("failed to list all log files with pattern %q: %v", pattern, err) + } + + for _, l := range logs { + if err := c.osInterface.Remove(l); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to remove container %q log %q: %v", containerID, l, err) + } + } + + return nil +} + func (c *containerLogManager) rotateLogs() error { + c.mutex.Lock() + defer c.mutex.Unlock() // TODO(#59998): Use kubelet pod cache. containers, err := c.runtimeService.ListContainers(&runtimeapi.ContainerFilter{}) if err != nil { @@ -197,7 +230,7 @@ func (c *containerLogManager) rotateLogs() error { continue } path := status.GetLogPath() - info, err := os.Stat(path) + info, err := c.osInterface.Stat(path) if err != nil { if !os.IsNotExist(err) { klog.Errorf("Failed to stat container log %q: %v", path, err) @@ -211,7 +244,7 @@ func (c *containerLogManager) rotateLogs() error { continue } // The container log should be recovered. - info, err = os.Stat(path) + info, err = c.osInterface.Stat(path) if err != nil { klog.Errorf("Failed to stat container log %q after reopen: %v", path, err) continue @@ -269,7 +302,7 @@ func (c *containerLogManager) rotateLog(id, log string) error { func (c *containerLogManager) cleanupUnusedLogs(logs []string) ([]string, error) { inuse, unused := filterUnusedLogs(logs) for _, l := range unused { - if err := os.Remove(l); err != nil { + if err := c.osInterface.Remove(l); err != nil { return nil, fmt.Errorf("failed to remove unused log %q: %v", l, err) } } @@ -322,7 +355,7 @@ func (c *containerLogManager) removeExcessLogs(logs []string) ([]string, error) } i := 0 for ; i < len(logs)-maxRotatedFiles; i++ { - if err := os.Remove(logs[i]); err != nil { + if err := c.osInterface.Remove(logs[i]); err != nil { return nil, fmt.Errorf("failed to remove old log %q: %v", logs[i], err) } } @@ -332,19 +365,19 @@ func (c *containerLogManager) removeExcessLogs(logs []string) ([]string, error) // compressLog compresses a log to log.gz with gzip. func (c *containerLogManager) compressLog(log string) error { - r, err := os.Open(log) + r, err := c.osInterface.Open(log) if err != nil { return fmt.Errorf("failed to open log %q: %v", log, err) } defer r.Close() tmpLog := log + tmpSuffix - f, err := os.OpenFile(tmpLog, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + f, err := c.osInterface.OpenFile(tmpLog, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { return fmt.Errorf("failed to create temporary log %q: %v", tmpLog, err) } defer func() { // Best effort cleanup of tmpLog. - os.Remove(tmpLog) + c.osInterface.Remove(tmpLog) }() defer f.Close() w := gzip.NewWriter(f) @@ -353,11 +386,11 @@ func (c *containerLogManager) compressLog(log string) error { return fmt.Errorf("failed to compress %q to %q: %v", log, tmpLog, err) } compressedLog := log + compressSuffix - if err := os.Rename(tmpLog, compressedLog); err != nil { + if err := c.osInterface.Rename(tmpLog, compressedLog); err != nil { return fmt.Errorf("failed to rename %q to %q: %v", tmpLog, compressedLog, err) } // Remove old log file. - if err := os.Remove(log); err != nil { + if err := c.osInterface.Remove(log); err != nil { return fmt.Errorf("failed to remove log %q after compress: %v", log, err) } return nil @@ -368,14 +401,14 @@ func (c *containerLogManager) compressLog(log string) error { func (c *containerLogManager) rotateLatestLog(id, log string) error { timestamp := c.clock.Now().Format(timestampFormat) rotated := fmt.Sprintf("%s.%s", log, timestamp) - if err := os.Rename(log, rotated); err != nil { + if err := c.osInterface.Rename(log, rotated); err != nil { return fmt.Errorf("failed to rotate log %q to %q: %v", log, rotated, err) } if err := c.runtimeService.ReopenContainerLog(id); err != nil { // Rename the rotated log back, so that we can try rotating it again // next round. // If kubelet gets restarted at this point, we'll lose original log. - if renameErr := os.Rename(rotated, log); renameErr != nil { + if renameErr := c.osInterface.Rename(rotated, log); renameErr != nil { // This shouldn't happen. // Report an error if this happens, because we will lose original // log. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/logs/container_log_manager_stub.go b/vendor/k8s.io/kubernetes/pkg/kubelet/logs/container_log_manager_stub.go index a6e0729f19de..27db1e42cbf3 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/logs/container_log_manager_stub.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/logs/container_log_manager_stub.go @@ -20,6 +20,10 @@ type containerLogManagerStub struct{} func (*containerLogManagerStub) Start() {} +func (*containerLogManagerStub) Clean(containerID string) error { + return nil +} + // NewStubContainerLogManager returns an empty ContainerLogManager which does nothing. func NewStubContainerLogManager() ContainerLogManager { return &containerLogManagerStub{} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/oom/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/oom/BUILD index 91bede4fb309..e38b2f80a37f 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/oom/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/oom/BUILD @@ -12,6 +12,9 @@ go_library( deps = [ "//staging/src/k8s.io/api/core/v1:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//staging/src/k8s.io/client-go/tools/record:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library", @@ -27,9 +30,15 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//staging/src/k8s.io/client-go/tools/record:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//staging/src/k8s.io/client-go/tools/record:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//staging/src/k8s.io/client-go/tools/record:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//staging/src/k8s.io/client-go/tools/record:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher.go index 7d4522b77b99..f4cacfe03160 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher.go @@ -21,7 +21,6 @@ import ( "os" "runtime" "strings" - "time" "github.com/fsnotify/fsnotify" "k8s.io/klog/v2" @@ -36,7 +35,6 @@ type Watcher struct { path string fs utilfs.Filesystem fsWatcher *fsnotify.Watcher - stopped chan struct{} desiredStateOfWorld cache.DesiredStateOfWorld } @@ -53,8 +51,6 @@ func NewWatcher(sockDir string, desiredStateOfWorld cache.DesiredStateOfWorld) * func (w *Watcher) Start(stopCh <-chan struct{}) error { klog.V(2).Infof("Plugin Watcher Start at %s", w.path) - w.stopped = make(chan struct{}) - // Creating the directory to be watched if it doesn't exist yet, // and walks through the directory to discover the existing plugins. if err := w.init(); err != nil { @@ -73,7 +69,6 @@ func (w *Watcher) Start(stopCh <-chan struct{}) error { } go func(fsWatcher *fsnotify.Watcher) { - defer close(w.stopped) for { select { case event := <-fsWatcher.Events: @@ -93,14 +88,6 @@ func (w *Watcher) Start(stopCh <-chan struct{}) error { } continue case <-stopCh: - // In case of plugin watcher being stopped by plugin manager, stop - // probing the creation/deletion of plugin sockets. - // Also give all pending go routines a chance to complete - select { - case <-w.stopped: - case <-time.After(11 * time.Second): - klog.Errorf("timeout on stopping watcher") - } w.fsWatcher.Close() return } @@ -123,6 +110,12 @@ func (w *Watcher) init() error { // Walks through the plugin directory discover any existing plugin sockets. // Ignore all errors except root dir not being walkable func (w *Watcher) traversePluginDir(dir string) error { + // watch the new dir + err := w.fsWatcher.Add(dir) + if err != nil { + return fmt.Errorf("failed to watch %s, err: %v", w.path, err) + } + // traverse existing children in the dir return w.fs.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { if path == dir { @@ -133,6 +126,11 @@ func (w *Watcher) traversePluginDir(dir string) error { return nil } + // do not call fsWatcher.Add twice on the root dir to avoid potential problems. + if path == dir { + return nil + } + switch mode := info.Mode(); { case mode.IsDir(): if err := w.fsWatcher.Add(path); err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/server/BUILD index 31bc8a2e6eb2..29fad991b98e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/BUILD @@ -18,6 +18,7 @@ go_library( "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/v1/validation:go_default_library", + "//pkg/features:go_default_library", "//pkg/kubelet/apis/podresources:go_default_library", "//pkg/kubelet/apis/podresources/v1alpha1:go_default_library", "//pkg/kubelet/apis/resourcemetrics/v1alpha1:go_default_library", @@ -45,6 +46,7 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/server/healthz:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/httplog:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/routes:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/flushwriter:go_default_library", "//staging/src/k8s.io/component-base/configz:go_default_library", "//staging/src/k8s.io/component-base/logs:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go index 92a268c69894..ca75a8b83153 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go @@ -55,6 +55,7 @@ import ( "k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/httplog" "k8s.io/apiserver/pkg/server/routes" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/apiserver/pkg/util/flushwriter" "k8s.io/component-base/configz" "k8s.io/component-base/logs" @@ -63,6 +64,7 @@ import ( "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core/v1/validation" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/apis/podresources" podresourcesapi "k8s.io/kubernetes/pkg/kubelet/apis/podresources/v1alpha1" "k8s.io/kubernetes/pkg/kubelet/apis/resourcemetrics/v1alpha1" @@ -350,16 +352,22 @@ func (s *Server) InstallDefaultHandlers(enableCAdvisorJSONEndpoints bool) { r := compbasemetrics.NewKubeRegistry() includedMetrics := cadvisormetrics.MetricSet{ - cadvisormetrics.CpuUsageMetrics: struct{}{}, - cadvisormetrics.MemoryUsageMetrics: struct{}{}, - cadvisormetrics.CpuLoadMetrics: struct{}{}, - cadvisormetrics.DiskIOMetrics: struct{}{}, - cadvisormetrics.DiskUsageMetrics: struct{}{}, - cadvisormetrics.NetworkUsageMetrics: struct{}{}, - cadvisormetrics.AcceleratorUsageMetrics: struct{}{}, - cadvisormetrics.AppMetrics: struct{}{}, - cadvisormetrics.ProcessMetrics: struct{}{}, + cadvisormetrics.CpuUsageMetrics: struct{}{}, + cadvisormetrics.MemoryUsageMetrics: struct{}{}, + cadvisormetrics.CpuLoadMetrics: struct{}{}, + cadvisormetrics.DiskIOMetrics: struct{}{}, + cadvisormetrics.DiskUsageMetrics: struct{}{}, + cadvisormetrics.NetworkUsageMetrics: struct{}{}, + cadvisormetrics.AppMetrics: struct{}{}, + cadvisormetrics.ProcessMetrics: struct{}{}, } + + // Only add the Accelerator metrics if the feature is inactive + // Note: Accelerator metrics will be removed in the future, hence the feature gate. + if !utilfeature.DefaultFeatureGate.Enabled(features.DisableAcceleratorUsageMetrics) { + includedMetrics.Add(cadvisormetrics.MetricKind(cadvisormetrics.AcceleratorUsageMetrics)) + } + cadvisorOpts := cadvisorv2.RequestOptions{ IdType: cadvisorv2.TypeName, Count: 1, diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/BUILD index 6cb3006598e3..401de4ab1811 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/BUILD @@ -55,6 +55,10 @@ go_test( "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/mock:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/kubelet/cm:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/kubelet/cm:go_default_library", "//vendor/github.com/google/gofuzz:go_default_library", @@ -71,10 +75,18 @@ go_test( "//pkg/kubelet/cm:go_default_library", "//vendor/github.com/google/gofuzz:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/kubelet/cm:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//pkg/kubelet/cm:go_default_library", "//vendor/github.com/google/gofuzz:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/kubelet/cm:go_default_library", + "//vendor/github.com/google/gofuzz:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/kubelet/cm:go_default_library", "//vendor/github.com/google/gofuzz:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/BUILD index ce128b9e8e5a..5317dfd86db5 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/BUILD @@ -12,6 +12,9 @@ go_library( deps = [ "//staging/src/k8s.io/api/core/v1:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", @@ -25,9 +28,15 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go index bdaa7ec32e23..e4c30ffbfd97 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go @@ -189,12 +189,6 @@ func (m *manager) SetPodStatus(pod *v1.Pod, status v1.PodStatus) { m.podStatusesLock.Lock() defer m.podStatusesLock.Unlock() - for _, c := range pod.Status.Conditions { - if !kubetypes.PodConditionByKubelet(c.Type) { - klog.Errorf("Kubelet is trying to update pod condition %q for pod %q. "+ - "But it is not owned by kubelet.", string(c.Type), format.Pod(pod)) - } - } // Make sure we're caching a deep copy. status = *status.DeepCopy() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/time_cache.go b/vendor/k8s.io/kubernetes/pkg/kubelet/time_cache.go new file mode 100644 index 000000000000..66528e25729c --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/time_cache.go @@ -0,0 +1,67 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubelet + +import ( + "sync" + "time" + + "github.com/golang/groupcache/lru" + + "k8s.io/apimachinery/pkg/types" +) + +// timeCache stores a time keyed by uid +type timeCache struct { + lock sync.RWMutex + cache *lru.Cache +} + +// maxTimeCacheEntries is the cache entry number in lru cache. 1000 is a proper number +// for our 100 pods per node target. If we support more pods per node in the future, we +// may want to increase the number. +const maxTimeCacheEntries = 1000 + +func newTimeCache() *timeCache { + return &timeCache{cache: lru.New(maxTimeCacheEntries)} +} + +func (c *timeCache) Add(uid types.UID, t time.Time) { + c.lock.Lock() + defer c.lock.Unlock() + c.cache.Add(uid, t) +} + +func (c *timeCache) Remove(uid types.UID) { + c.lock.Lock() + defer c.lock.Unlock() + c.cache.Remove(uid) +} + +func (c *timeCache) Get(uid types.UID) (time.Time, bool) { + c.lock.RLock() + defer c.lock.RUnlock() + value, ok := c.cache.Get(uid) + if !ok { + return time.Time{}, false + } + t, ok := value.(time.Time) + if !ok { + return time.Time{}, false + } + return t, true +} diff --git a/vendor/k8s.io/kubernetes/pkg/proxy/userspace/BUILD b/vendor/k8s.io/kubernetes/pkg/proxy/userspace/BUILD index 4f292e73399c..472830df4afe 100644 --- a/vendor/k8s.io/kubernetes/pkg/proxy/userspace/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/proxy/userspace/BUILD @@ -38,6 +38,9 @@ go_library( "//vendor/k8s.io/utils/exec:go_default_library", "//vendor/k8s.io/utils/net:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//vendor/golang.org/x/sys/unix:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//vendor/golang.org/x/sys/unix:go_default_library", ], @@ -50,9 +53,15 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//vendor/golang.org/x/sys/unix:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//vendor/golang.org/x/sys/unix:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//vendor/golang.org/x/sys/unix:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//vendor/golang.org/x/sys/unix:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//vendor/golang.org/x/sys/unix:go_default_library", ], diff --git a/vendor/k8s.io/kubernetes/pkg/registry/core/endpoint/BUILD b/vendor/k8s.io/kubernetes/pkg/registry/core/endpoint/BUILD index 9a88912bcedb..76bd3e14fb6b 100644 --- a/vendor/k8s.io/kubernetes/pkg/registry/core/endpoint/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/registry/core/endpoint/BUILD @@ -13,7 +13,6 @@ go_library( ], importpath = "k8s.io/kubernetes/pkg/registry/core/endpoint", deps = [ - "//pkg/api/endpoints:go_default_library", "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/core/validation:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/registry/core/endpoint/strategy.go b/vendor/k8s.io/kubernetes/pkg/registry/core/endpoint/strategy.go index af8d1233f7ec..9feb751ae84b 100644 --- a/vendor/k8s.io/kubernetes/pkg/registry/core/endpoint/strategy.go +++ b/vendor/k8s.io/kubernetes/pkg/registry/core/endpoint/strategy.go @@ -22,7 +22,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/storage/names" - endptspkg "k8s.io/kubernetes/pkg/api/endpoints" "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core/validation" @@ -60,8 +59,6 @@ func (endpointsStrategy) Validate(ctx context.Context, obj runtime.Object) field // Canonicalize normalizes the object after validation. func (endpointsStrategy) Canonicalize(obj runtime.Object) { - endpoints := obj.(*api.Endpoints) - endpoints.Subsets = endptspkg.RepackSubsets(endpoints.Subsets) } // AllowCreateOnUpdate is true for endpoints. diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1/types.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1/types.go index 1e464bf9c976..c878a7c9ffad 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1/types.go @@ -73,6 +73,7 @@ type PodInfo struct { RequiredAntiAffinityTerms []AffinityTerm PreferredAffinityTerms []WeightedAffinityTerm PreferredAntiAffinityTerms []WeightedAffinityTerm + ParseError error } // AffinityTerm is a processed version of v1.PodAffinityTerm. @@ -88,53 +89,50 @@ type WeightedAffinityTerm struct { Weight int32 } -func newAffinityTerm(pod *v1.Pod, term *v1.PodAffinityTerm) *AffinityTerm { +func newAffinityTerm(pod *v1.Pod, term *v1.PodAffinityTerm) (*AffinityTerm, error) { namespaces := schedutil.GetNamespacesFromPodAffinityTerm(pod, term) selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) if err != nil { - klog.Errorf("Cannot process label selector: %v", err) - return nil + return nil, err } - return &AffinityTerm{Namespaces: namespaces, Selector: selector, TopologyKey: term.TopologyKey} + return &AffinityTerm{Namespaces: namespaces, Selector: selector, TopologyKey: term.TopologyKey}, nil } // getAffinityTerms receives a Pod and affinity terms and returns the namespaces and // selectors of the terms. -func getAffinityTerms(pod *v1.Pod, v1Terms []v1.PodAffinityTerm) []AffinityTerm { +func getAffinityTerms(pod *v1.Pod, v1Terms []v1.PodAffinityTerm) ([]AffinityTerm, error) { if v1Terms == nil { - return nil + return nil, nil } var terms []AffinityTerm for _, term := range v1Terms { - t := newAffinityTerm(pod, &term) - if t == nil { - // We get here if the label selector failed to process, this is not supposed - // to happen because the pod should have been validated by the api server. - return nil + t, err := newAffinityTerm(pod, &term) + if err != nil { + // We get here if the label selector failed to process + return nil, err } terms = append(terms, *t) } - return terms + return terms, nil } // getWeightedAffinityTerms returns the list of processed affinity terms. -func getWeightedAffinityTerms(pod *v1.Pod, v1Terms []v1.WeightedPodAffinityTerm) []WeightedAffinityTerm { +func getWeightedAffinityTerms(pod *v1.Pod, v1Terms []v1.WeightedPodAffinityTerm) ([]WeightedAffinityTerm, error) { if v1Terms == nil { - return nil + return nil, nil } var terms []WeightedAffinityTerm for _, term := range v1Terms { - t := newAffinityTerm(pod, &term.PodAffinityTerm) - if t == nil { - // We get here if the label selector failed to process, this is not supposed - // to happen because the pod should have been validated by the api server. - return nil + t, err := newAffinityTerm(pod, &term.PodAffinityTerm) + if err != nil { + // We get here if the label selector failed to process + return nil, err } terms = append(terms, WeightedAffinityTerm{AffinityTerm: *t, Weight: term.Weight}) } - return terms + return terms, nil } // NewPodInfo return a new PodInfo @@ -150,12 +148,32 @@ func NewPodInfo(pod *v1.Pod) *PodInfo { } } + // Attempt to parse the affinity terms + var parseErr error + requiredAffinityTerms, err := getAffinityTerms(pod, schedutil.GetPodAffinityTerms(pod.Spec.Affinity)) + if err != nil { + parseErr = fmt.Errorf("requiredAffinityTerms: %w", err) + } + requiredAntiAffinityTerms, err := getAffinityTerms(pod, schedutil.GetPodAntiAffinityTerms(pod.Spec.Affinity)) + if err != nil { + parseErr = fmt.Errorf("requiredAntiAffinityTerms: %w", err) + } + weightedAffinityTerms, err := getWeightedAffinityTerms(pod, preferredAffinityTerms) + if err != nil { + parseErr = fmt.Errorf("preferredAffinityTerms: %w", err) + } + weightedAntiAffinityTerms, err := getWeightedAffinityTerms(pod, preferredAntiAffinityTerms) + if err != nil { + parseErr = fmt.Errorf("preferredAntiAffinityTerms: %w", err) + } + return &PodInfo{ Pod: pod, - RequiredAffinityTerms: getAffinityTerms(pod, schedutil.GetPodAffinityTerms(pod.Spec.Affinity)), - RequiredAntiAffinityTerms: getAffinityTerms(pod, schedutil.GetPodAntiAffinityTerms(pod.Spec.Affinity)), - PreferredAffinityTerms: getWeightedAffinityTerms(pod, preferredAffinityTerms), - PreferredAntiAffinityTerms: getWeightedAffinityTerms(pod, preferredAntiAffinityTerms), + RequiredAffinityTerms: requiredAffinityTerms, + RequiredAntiAffinityTerms: requiredAntiAffinityTerms, + PreferredAffinityTerms: weightedAffinityTerms, + PreferredAntiAffinityTerms: weightedAntiAffinityTerms, + ParseError: parseErr, } } @@ -607,6 +625,12 @@ func (n *NodeInfo) SetNode(node *v1.Node) error { return nil } +// RemoveNode removes the node object, leaving all other tracking information. +func (n *NodeInfo) RemoveNode() { + n.node = nil + n.Generation = nextGeneration() +} + // FilterOutPods receives a list of pods and filters out those whose node names // are equal to the node of this NodeInfo, but are not found in the pods of this NodeInfo. // diff --git a/vendor/k8s.io/kubernetes/pkg/util/ipvs/BUILD b/vendor/k8s.io/kubernetes/pkg/util/ipvs/BUILD index 441e86842eb4..ddc7c45e917a 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/ipvs/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/util/ipvs/BUILD @@ -38,6 +38,9 @@ go_library( deps = [ "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//vendor/k8s.io/utils/exec:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//vendor/github.com/moby/ipvs:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", @@ -53,9 +56,15 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//vendor/k8s.io/utils/exec:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//vendor/k8s.io/utils/exec:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//vendor/k8s.io/utils/exec:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//vendor/k8s.io/utils/exec:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//vendor/github.com/moby/ipvs:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/util/resizefs/BUILD b/vendor/k8s.io/kubernetes/pkg/util/resizefs/BUILD index 9e32e2ce0ed0..7578dd40b832 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/resizefs/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/util/resizefs/BUILD @@ -9,6 +9,9 @@ go_library( importpath = "k8s.io/kubernetes/pkg/util/resizefs", visibility = ["//visibility:public"], deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//vendor/k8s.io/utils/mount:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/utils/mount:go_default_library", @@ -22,9 +25,15 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//vendor/k8s.io/utils/mount:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//vendor/k8s.io/utils/mount:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//vendor/k8s.io/utils/mount:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//vendor/k8s.io/utils/mount:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/utils/mount:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/BUILD b/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/BUILD index 1273d3f2b46d..b2029d31467e 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/BUILD @@ -42,6 +42,9 @@ go_library( "//vendor/k8s.io/utils/mount:go_default_library", "//vendor/k8s.io/utils/strings:go_default_library", ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//vendor/k8s.io/utils/exec:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//vendor/k8s.io/utils/exec:go_default_library", ], @@ -54,9 +57,15 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//vendor/k8s.io/utils/exec:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//vendor/k8s.io/utils/exec:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//vendor/k8s.io/utils/exec:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//vendor/k8s.io/utils/exec:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//vendor/k8s.io/utils/exec:go_default_library", ], diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fs/BUILD b/vendor/k8s.io/kubernetes/pkg/volume/util/fs/BUILD index 07da6389c2bd..b51ee597b530 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fs/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fs/BUILD @@ -10,6 +10,9 @@ go_library( importpath = "k8s.io/kubernetes/pkg/volume/util/fs", visibility = ["//visibility:public"], deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/volume/util/fsquota:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", @@ -26,11 +29,17 @@ go_library( "@io_bazel_rules_go//go/platform:freebsd": [ "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//pkg/volume/util/fsquota:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/golang.org/x/sys/unix:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/volume/util/fsquota:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/BUILD b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/BUILD index f04480da7de7..ff6b29374e0f 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/BUILD @@ -11,6 +11,10 @@ go_library( importpath = "k8s.io/kubernetes/pkg/volume/util/subpath", visibility = ["//visibility:public"], deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//vendor/k8s.io/utils/mount:go_default_library", + "//vendor/k8s.io/utils/nsenter:go_default_library", + ], "@io_bazel_rules_go//go/platform:android": [ "//pkg/volume/util/hostutil:go_default_library", "//vendor/golang.org/x/sys/unix:go_default_library", @@ -29,10 +33,18 @@ go_library( "//vendor/k8s.io/utils/mount:go_default_library", "//vendor/k8s.io/utils/nsenter:go_default_library", ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//vendor/k8s.io/utils/mount:go_default_library", + "//vendor/k8s.io/utils/nsenter:go_default_library", + ], "@io_bazel_rules_go//go/platform:ios": [ "//vendor/k8s.io/utils/mount:go_default_library", "//vendor/k8s.io/utils/nsenter:go_default_library", ], + "@io_bazel_rules_go//go/platform:js": [ + "//vendor/k8s.io/utils/mount:go_default_library", + "//vendor/k8s.io/utils/nsenter:go_default_library", + ], "@io_bazel_rules_go//go/platform:linux": [ "//pkg/volume/util/hostutil:go_default_library", "//vendor/golang.org/x/sys/unix:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go index 79ffb859ed51..2e08449c8898 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go @@ -31,6 +31,10 @@ import ( "k8s.io/utils/nsenter" ) +// MaxPathLength is the maximum length of Windows path. Normally, it is 260, but if long path is enable, +// the max number is 32,767 +const MaxPathLength = 32767 + type subpath struct{} // New returns a subpath.Interface for the current system @@ -44,32 +48,93 @@ func NewNSEnter(mounter mount.Interface, ne *nsenter.Nsenter, rootDir string) In return nil } -// evalPath returns the path name after the evaluation of any symbolic links. -// If the path after evaluation starts with Volume or \??\Volume, it means that it was a symlink from -// volume (represented by volumeID) to the given path. In this case, the given path is returned. -func evalPath(path string) (linkedPath string, err error) { - cmd := fmt.Sprintf("Get-Item -Path %s | Select-Object -ExpandProperty Target", path) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() - klog.V(4).Infof("evaluate symlink from %s: %s %v", path, string(output), err) - if err != nil { - return "", err - } - linkedPath = strings.TrimSpace(string(output)) - if isVolumePrefix(linkedPath) { - return path, err +// isDriveLetterPath returns true if the given path is empty or it ends with ":" or ":\" or ":\\" +func isDriveLetterorEmptyPath(path string) bool { + if path == "" || strings.HasSuffix(path, ":\\\\") || strings.HasSuffix(path, ":") || strings.HasSuffix(path, ":\\") { + return true } - return linkedPath, err + return false } // isVolumePrefix returns true if the given path name starts with "Volume" or volume prefix including -// "\\.\" or "\\?\". Otherwise, it returns false. -func isVolumePrefix(path string) bool { - if strings.HasPrefix(path, "Volume") || strings.HasPrefix(path, "\\\\?\\") || strings.HasPrefix(path, "\\\\.\\") { +// "\\.\", "\\?\" for device path or "UNC" or "\\" for UNC path. Otherwise, it returns false. +func isDeviceOrUncPath(path string) bool { + if strings.HasPrefix(path, "Volume") || strings.HasPrefix(path, "\\\\?\\") || strings.HasPrefix(path, "\\\\.\\") || strings.HasPrefix(path, "UNC") { return true } return false } +// getUpperPath removes the last level of directory. +func getUpperPath(path string) string { + sep := fmt.Sprintf("%c", filepath.Separator) + upperpath := strings.TrimSuffix(path, sep) + return filepath.Dir(upperpath) +} + +// Check whether a directory/file is a link type or not +// LinkType could be SymbolicLink, Junction, or HardLink +func isLinkPath(path string) (bool, error) { + cmd := fmt.Sprintf("(Get-Item -Path %s).LinkType", path) + output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() + if err != nil { + return false, err + } + if strings.TrimSpace(string(output)) != "" { + return true, nil + } + return false, nil +} + +// evalSymlink returns the path name after the evaluation of any symbolic links. +// If the path after evaluation is a device path or network connection, the original path is returned +func evalSymlink(path string) (string, error) { + path = mount.NormalizeWindowsPath(path) + if isDeviceOrUncPath(path) || isDriveLetterorEmptyPath(path) { + klog.V(4).Infof("Path '%s' is not a symlink, return its original form.", path) + return path, nil + } + upperpath := path + base := "" + for i := 0; i < MaxPathLength; i++ { + isLink, err := isLinkPath(upperpath) + if err != nil { + return "", err + } + if isLink { + break + } + // continue to check next layer + base = filepath.Join(filepath.Base(upperpath), base) + upperpath = getUpperPath(upperpath) + if isDriveLetterorEmptyPath(upperpath) { + klog.V(4).Infof("Path '%s' is not a symlink, return its original form.", path) + return path, nil + } + } + // This command will give the target path of a given symlink + cmd := fmt.Sprintf("(Get-Item -Path %s).Target", upperpath) + output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() + if err != nil { + return "", err + } + klog.V(4).Infof("evaluate path %s: symlink from %s to %s", path, upperpath, string(output)) + linkedPath := strings.TrimSpace(string(output)) + if linkedPath == "" || isDeviceOrUncPath(linkedPath) { + klog.V(4).Infof("Path '%s' has a target %s. Return its original form.", path, linkedPath) + return path, nil + } + // If the target is not an absoluate path, join iit with the current upperpath + if !filepath.IsAbs(linkedPath) { + linkedPath = filepath.Join(getUpperPath(upperpath), linkedPath) + } + nextLink, err := evalSymlink(linkedPath) + if err != nil { + return path, err + } + return filepath.Join(nextLink, base), nil +} + // check whether hostPath is within volume path // this func will lock all intermediate subpath directories, need to close handle outside of this func after container started func lockAndCheckSubPath(volumePath, hostPath string) ([]uintptr, error) { @@ -77,12 +142,12 @@ func lockAndCheckSubPath(volumePath, hostPath string) ([]uintptr, error) { return []uintptr{}, nil } - finalSubPath, err := evalPath(hostPath) + finalSubPath, err := evalSymlink(hostPath) if err != nil { return []uintptr{}, fmt.Errorf("cannot evaluate link %s: %s", hostPath, err) } - finalVolumePath, err := evalPath(volumePath) + finalVolumePath, err := evalSymlink(volumePath) if err != nil { return []uintptr{}, fmt.Errorf("cannot read link %s: %s", volumePath, err) } @@ -190,7 +255,7 @@ func (sp *subpath) CleanSubPaths(podDir string, volumeName string) error { // SafeMakeDir makes sure that the created directory does not escape given base directory mis-using symlinks. func (sp *subpath) SafeMakeDir(subdir string, base string, perm os.FileMode) error { - realBase, err := evalPath(base) + realBase, err := evalSymlink(base) if err != nil { return fmt.Errorf("error resolving symlinks in %s: %s", base, err) } @@ -229,11 +294,11 @@ func doSafeMakeDir(pathname string, base string, perm os.FileMode) error { } // Ensure the existing directory is inside allowed base - fullExistingPath, err := evalPath(existingPath) + fullExistingPath, err := evalSymlink(existingPath) if err != nil { return fmt.Errorf("error opening existing directory %s: %s", existingPath, err) } - fullBasePath, err := evalPath(base) + fullBasePath, err := evalSymlink(base) if err != nil { return fmt.Errorf("cannot read link %s: %s", base, err) } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go index d7b8e87c7da2..ebef818d2a9b 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go @@ -23,6 +23,7 @@ import ( "syscall" "os" + "time" v1 "k8s.io/api/core/v1" utilfeature "k8s.io/apiserver/pkg/util/feature" @@ -46,7 +47,10 @@ func SetVolumeOwnership(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1 fsGroupPolicyEnabled := utilfeature.DefaultFeatureGate.Enabled(features.ConfigurableFSGroupPolicy) - klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", mounter.GetPath()) + timer := time.AfterFunc(30*time.Second, func() { + klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", mounter.GetPath()) + }) + defer timer.Stop() // This code exists for legacy purposes, so as old behaviour is entirely preserved when feature gate is disabled // TODO: remove this when ConfigurableFSGroupPolicy turns GA. diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go b/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go index a00e33c1478d..f11a0412223a 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go @@ -160,6 +160,7 @@ func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding) eventsRule(), }, }) + addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "endpointslicemirroring-controller"}, Rules: []rbacv1.PolicyRule{ diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/BUILD b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/BUILD index f57debecae87..31d7e02a2183 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/BUILD @@ -21,6 +21,7 @@ go_library( "framework.go", "garbage_collector.go", "generated_clientset.go", + "health_handlers.go", "namespace.go", "protocol.go", "resource_quota.go", @@ -62,6 +63,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/aggregator.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/aggregator.go index a708ae1ed4e2..94c766283943 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/aggregator.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/aggregator.go @@ -90,6 +90,7 @@ var _ = SIGDescribe("Aggregator", func() { }) /* + Release: v1.17 Testname: aggregator-supports-the-sample-apiserver Description: Ensure that the sample-apiserver code from 1.17 and compiled against 1.17 will work on the current Aggregator/API-Server. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/certs.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/certs.go index d9926f85e2ca..406a7c6367b1 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/certs.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/certs.go @@ -63,6 +63,7 @@ func setupServerCert(namespaceName, serviceName string) *certContext { signedCert, err := utils.NewSignedCert( &cert.Config{ CommonName: serviceName + "." + namespaceName + ".svc", + AltNames: cert.AltNames{DNSNames: []string{serviceName + "." + namespaceName + ".svc"}}, Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, }, key, signingCert, signingKey, diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/crd_conversion_webhook.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/crd_conversion_webhook.go index 414b961e4c6f..477d12c8cce2 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/crd_conversion_webhook.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/crd_conversion_webhook.go @@ -139,7 +139,7 @@ var _ = SIGDescribe("CustomResourceConversionWebhook [Privileged:ClusterAdmin]", }) /* - Release : v1.16 + Release: v1.16 Testname: Custom Resource Definition Conversion Webhook, conversion custom resource Description: Register a conversion webhook and a custom resource definition. Create a v1 custom resource. Attempts to read it at v2 MUST succeed. @@ -173,7 +173,7 @@ var _ = SIGDescribe("CustomResourceConversionWebhook [Privileged:ClusterAdmin]", }) /* - Release : v1.16 + Release: v1.16 Testname: Custom Resource Definition Conversion Webhook, convert mixed version list Description: Register a conversion webhook and a custom resource definition. Create a custom resource stored at v1. Change the custom resource definition storage to v2. Create a custom resource stored at v2. Attempt to list diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/custom_resource_definition.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/custom_resource_definition.go index a0123a4445d9..1d4c5ecaf6d6 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/custom_resource_definition.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/custom_resource_definition.go @@ -47,7 +47,7 @@ var _ = SIGDescribe("CustomResourceDefinition resources [Privileged:ClusterAdmin ginkgo.Context("Simple CustomResourceDefinition", func() { /* - Release : v1.9 + Release: v1.9 Testname: Custom Resource Definition, create Description: Create a API extension client and define a random custom resource definition. Create the custom resource definition and then delete it. The creation and deletion MUST @@ -73,7 +73,7 @@ var _ = SIGDescribe("CustomResourceDefinition resources [Privileged:ClusterAdmin }) /* - Release : v1.16 + Release: v1.16 Testname: Custom Resource Definition, list Description: Create a API extension client, define 10 labeled custom resource definitions and list them using a label selector; the list result MUST contain only the labeled custom resource definitions. Delete the labeled @@ -135,7 +135,7 @@ var _ = SIGDescribe("CustomResourceDefinition resources [Privileged:ClusterAdmin }) /* - Release : v1.16 + Release: v1.16 Testname: Custom Resource Definition, status sub-resource Description: Create a custom resource definition. Attempt to read, update and patch its status sub-resource; all mutating sub-resource operations MUST be visible to subsequent reads. @@ -258,7 +258,7 @@ var _ = SIGDescribe("CustomResourceDefinition resources [Privileged:ClusterAdmin }) /* - Release : v1.17 + Release: v1.17 Testname: Custom Resource Definition, defaulting Description: Create a custom resource definition without default. Create CR. Add default and read CR until the default is applied. Create another CR. Remove default, add default for another field and read CR until diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/discovery.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/discovery.go index 417fa79522d6..0fd964915713 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/discovery.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/discovery.go @@ -82,7 +82,13 @@ var _ = SIGDescribe("Discovery", func() { } }) - ginkgo.It("should validate PreferredVersion for each APIGroup", func() { + /* + Release : v1.19 + Testname: Discovery, confirm the PreferredVersion for each api group + Description: Ensure that a list of apis is retrieved. + Each api group found MUST return a valid PreferredVersion unless the group suffix is example.com. + */ + framework.ConformanceIt("should validate PreferredVersion for each APIGroup", func() { // get list of APIGroup endpoints list := &metav1.APIGroupList{} diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/events.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/events.go index 64ee846f258c..0bb5ff4f3718 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/events.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/events.go @@ -39,7 +39,7 @@ var _ = ginkgo.Describe("[sig-api-machinery] Events", func() { f := framework.NewDefaultFramework("events") /* - Release : v1.19 + Release: v1.19 Testname: Event resource lifecycle Description: Create an event, the event MUST exist. The event is patched with a new message, the check MUST have the update message. @@ -124,7 +124,7 @@ var _ = ginkgo.Describe("[sig-api-machinery] Events", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: Event, delete a collection Description: A set of events is created with a label selector which MUST be found when listed. The set of events is deleted and MUST NOT show up when listed by its label selector. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/garbage_collector.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/garbage_collector.go index 6870a11f285c..30db7bdb463f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/garbage_collector.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/garbage_collector.go @@ -320,7 +320,7 @@ var _ = SIGDescribe("Garbage collector", func() { f := framework.NewDefaultFramework("gc") /* - Release : v1.9 + Release: v1.9 Testname: Garbage Collector, delete replication controller, propagation policy background Description: Create a replication controller with 2 Pods. Once RC is created and the first Pod is created, delete RC with deleteOptions.PropagationPolicy set to Background. Deleting the Replication Controller MUST cause pods created by that RC to be deleted. */ @@ -378,7 +378,7 @@ var _ = SIGDescribe("Garbage collector", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Garbage Collector, delete replication controller, propagation policy orphan Description: Create a replication controller with maximum allocatable Pods between 10 and 100 replicas. Once RC is created and the all Pods are created, delete RC with deleteOptions.PropagationPolicy set to Orphan. Deleting the Replication Controller MUST cause pods created by that RC to be orphaned. */ @@ -499,7 +499,7 @@ var _ = SIGDescribe("Garbage collector", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Garbage Collector, delete deployment, propagation policy background Description: Create a deployment with a replicaset. Once replicaset is created , delete the deployment with deleteOptions.PropagationPolicy set to Background. Deleting the deployment MUST delete the replicaset created by the deployment and also the Pods that belong to the deployments MUST be deleted. */ @@ -558,7 +558,7 @@ var _ = SIGDescribe("Garbage collector", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Garbage Collector, delete deployment, propagation policy orphan Description: Create a deployment with a replicaset. Once replicaset is created , delete the deployment with deleteOptions.PropagationPolicy set to Orphan. Deleting the deployment MUST cause the replicaset created by the deployment to be orphaned, also the Pods created by the deployments MUST be orphaned. */ @@ -576,18 +576,34 @@ var _ = SIGDescribe("Garbage collector", func() { } // wait for deployment to create some rs ginkgo.By("Wait for the Deployment to create new ReplicaSet") + var replicaset appsv1.ReplicaSet err = wait.PollImmediate(500*time.Millisecond, 1*time.Minute, func() (bool, error) { rsList, err := rsClient.List(context.TODO(), metav1.ListOptions{}) if err != nil { return false, fmt.Errorf("failed to list rs: %v", err) } - return len(rsList.Items) > 0, nil + if len(rsList.Items) > 0 { + replicaset = rsList.Items[0] + return true, nil + } + return false, nil }) if err != nil { framework.Failf("Failed to wait for the Deployment to create some ReplicaSet: %v", err) } + desiredGeneration := replicaset.Generation + if err := wait.PollImmediate(100*time.Millisecond, 60*time.Second, func() (bool, error) { + newRS, err := clientSet.AppsV1().ReplicaSets(replicaset.Namespace).Get(context.TODO(), replicaset.Name, metav1.GetOptions{}) + if err != nil { + return false, err + } + return newRS.Status.ObservedGeneration >= desiredGeneration && newRS.Status.Replicas == *replicaset.Spec.Replicas, nil + }); err != nil { + framework.Failf("failed to verify .Status.Replicas is equal to .Spec.Replicas for replicaset %q: %v", replicaset.Name, err) + } + ginkgo.By("delete the deployment") deleteOptions := getOrphanOptions() deleteOptions.Preconditions = metav1.NewUIDPreconditions(string(createdDeployment.UID)) @@ -642,7 +658,7 @@ var _ = SIGDescribe("Garbage collector", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Garbage Collector, delete replication controller, after owned pods Description: Create a replication controller with maximum allocatable Pods between 10 and 100 replicas. Once RC is created and the all Pods are created, delete RC with deleteOptions.PropagationPolicy set to Foreground. Deleting the Replication Controller MUST cause pods created by that RC to be deleted before the RC is deleted. */ @@ -727,7 +743,7 @@ var _ = SIGDescribe("Garbage collector", func() { // TODO: this should be an integration test /* - Release : v1.9 + Release: v1.9 Testname: Garbage Collector, multiple owners Description: Create a replication controller RC1, with maximum allocatable Pods between 10 and 100 replicas. Create second replication controller RC2 and set RC2 as owner for half of those replicas. Once RC1 is created and the all Pods are created, delete RC1 with deleteOptions.PropagationPolicy set to Foreground. Half of the Pods that has RC2 as owner MUST not be deleted but have a deletion timestamp. Deleting the Replication Controller MUST not delete Pods that are owned by multiple replication controllers. */ @@ -841,7 +857,7 @@ var _ = SIGDescribe("Garbage collector", func() { // TODO: should be an integration test /* - Release : v1.9 + Release: v1.9 Testname: Garbage Collector, dependency cycle Description: Create three pods, patch them with Owner references such that pod1 has pod3, pod2 has pod1 and pod3 has pod2 as owner references respectively. Delete pod1 MUST delete all pods. The dependency cycle MUST not block the garbage collection. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/health_handlers.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/health_handlers.go new file mode 100644 index 000000000000..b67aa01945cc --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/health_handlers.go @@ -0,0 +1,133 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apimachinery + +import ( + "context" + "fmt" + "strings" + "time" + + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + clientset "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" + "k8s.io/kubernetes/test/e2e/framework" + + "github.com/onsi/ginkgo" +) + +var ( + requiredHealthzChecks = sets.NewString( + "[+]ping ok", + "[+]log ok", + "[+]etcd ok", + "[+]poststarthook/start-kube-apiserver-admission-initializer ok", + "[+]poststarthook/generic-apiserver-start-informers ok", + "[+]poststarthook/start-apiextensions-informers ok", + "[+]poststarthook/start-apiextensions-controllers ok", + "[+]poststarthook/crd-informer-synced ok", + "[+]poststarthook/bootstrap-controller ok", + "[+]poststarthook/scheduling/bootstrap-system-priority-classes ok", + "[+]poststarthook/start-cluster-authentication-info-controller ok", + "[+]poststarthook/start-kube-aggregator-informers ok", + "[+]poststarthook/apiservice-registration-controller ok", + "[+]poststarthook/apiservice-status-available-controller ok", + "[+]poststarthook/kube-apiserver-autoregistration ok", + "[+]autoregister-completion ok", + "[+]poststarthook/apiservice-openapi-controller ok", + ) + requiredLivezChecks = sets.NewString( + "[+]ping ok", + "[+]log ok", + "[+]etcd ok", + "[+]poststarthook/start-kube-apiserver-admission-initializer ok", + "[+]poststarthook/generic-apiserver-start-informers ok", + "[+]poststarthook/start-apiextensions-informers ok", + "[+]poststarthook/start-apiextensions-controllers ok", + "[+]poststarthook/crd-informer-synced ok", + "[+]poststarthook/bootstrap-controller ok", + "[+]poststarthook/scheduling/bootstrap-system-priority-classes ok", + "[+]poststarthook/start-cluster-authentication-info-controller ok", + "[+]poststarthook/start-kube-aggregator-informers ok", + "[+]poststarthook/apiservice-registration-controller ok", + "[+]poststarthook/apiservice-status-available-controller ok", + "[+]poststarthook/kube-apiserver-autoregistration ok", + "[+]autoregister-completion ok", + "[+]poststarthook/apiservice-openapi-controller ok", + ) + requiredReadyzChecks = sets.NewString( + "[+]ping ok", + "[+]log ok", + "[+]etcd ok", + "[+]informer-sync ok", + "[+]poststarthook/start-kube-apiserver-admission-initializer ok", + "[+]poststarthook/generic-apiserver-start-informers ok", + "[+]poststarthook/start-apiextensions-informers ok", + "[+]poststarthook/start-apiextensions-controllers ok", + "[+]poststarthook/crd-informer-synced ok", + "[+]poststarthook/bootstrap-controller ok", + "[+]poststarthook/scheduling/bootstrap-system-priority-classes ok", + "[+]poststarthook/start-cluster-authentication-info-controller ok", + "[+]poststarthook/start-kube-aggregator-informers ok", + "[+]poststarthook/apiservice-registration-controller ok", + "[+]poststarthook/apiservice-status-available-controller ok", + "[+]poststarthook/kube-apiserver-autoregistration ok", + "[+]autoregister-completion ok", + "[+]poststarthook/apiservice-openapi-controller ok", + ) +) + +func testPath(client clientset.Interface, path string, requiredChecks sets.String) error { + var result restclient.Result + err := wait.Poll(100*time.Millisecond, 30*time.Second, func() (bool, error) { + result = client.CoreV1().RESTClient().Get().RequestURI(path).Do(context.TODO()) + status := 0 + result.StatusCode(&status) + return status == 200, nil + }) + if err != nil { + return err + } + body, err := result.Raw() + if err != nil { + return err + } + checks := sets.NewString(strings.Split(string(body), "\n")...) + if missing := requiredChecks.Difference(checks); missing.Len() > 0 { + return fmt.Errorf("missing required %s checks: %v in: %s", path, missing, string(body)) + } + return nil +} + +var _ = SIGDescribe("health handlers", func() { + f := framework.NewDefaultFramework("health") + + ginkgo.It("should contain necessary checks", func() { + ginkgo.By("/health") + err := testPath(f.ClientSet, "/healthz?verbose=1", requiredHealthzChecks) + framework.ExpectNoError(err) + + ginkgo.By("/livez") + err = testPath(f.ClientSet, "/livez?verbose=1", requiredLivezChecks) + framework.ExpectNoError(err) + + ginkgo.By("/readyz") + err = testPath(f.ClientSet, "/readyz?verbose=1", requiredReadyzChecks) + framework.ExpectNoError(err) + }) +}) diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/namespace.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/namespace.go index 36f0c0825626..bf32faeb3314 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/namespace.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/namespace.go @@ -24,7 +24,7 @@ import ( "sync" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -228,6 +228,7 @@ var _ = SIGDescribe("Namespaces [Serial]", func() { f := framework.NewDefaultFramework("namespaces") /* + Release: v1.11 Testname: namespace-deletion-removes-pods Description: Ensure that if a namespace is deleted then all pods are removed from that namespace. */ @@ -235,6 +236,7 @@ var _ = SIGDescribe("Namespaces [Serial]", func() { func() { ensurePodsAreRemovedWhenNamespaceIsDeleted(f) }) /* + Release: v1.11 Testname: namespace-deletion-removes-services Description: Ensure that if a namespace is deleted then all services are removed from that namespace. */ @@ -249,7 +251,7 @@ var _ = SIGDescribe("Namespaces [Serial]", func() { func() { extinguish(f, 100, 0, 150) }) /* - Release : v1.18 + Release: v1.18 Testname: Namespace patching Description: A Namespace is created. The Namespace is patched. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/server_version.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/server_version.go index d7f7f7098bff..19331773dca6 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/server_version.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/server_version.go @@ -17,9 +17,10 @@ limitations under the License. package apimachinery import ( + "regexp" + "k8s.io/apimachinery/pkg/version" "k8s.io/kubernetes/test/e2e/framework" - "regexp" "github.com/onsi/ginkgo" ) @@ -28,7 +29,7 @@ var _ = SIGDescribe("server version", func() { f := framework.NewDefaultFramework("server-version") /* - Release : v1.19 + Release: v1.19 Testname: Confirm a server version Description: Ensure that an API server version can be retrieved. Both the major and minor versions MUST only be an integer. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/table_conversion.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/table_conversion.go index 8e1bb6ee9ebe..a5f337cd56ce 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/table_conversion.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/table_conversion.go @@ -146,7 +146,7 @@ var _ = SIGDescribe("Servers with support for Table transformation", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: API metadata HTTP return Description: Issue a HTTP request to the API. HTTP request MUST return a HTTP status code of 406. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/watch.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/watch.go index c75f4babd456..25911bfe7346 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/watch.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/watch.go @@ -22,7 +22,7 @@ import ( "math/rand" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -46,6 +46,7 @@ var _ = SIGDescribe("Watchers", func() { f := framework.NewDefaultFramework("watch") /* + Release: v1.11 Testname: watch-configmaps-with-multiple-watchers Description: Ensure that multiple watchers are able to receive all add, update, and delete notifications on configmaps that match a label selector and do @@ -132,6 +133,7 @@ var _ = SIGDescribe("Watchers", func() { }) /* + Release: v1.11 Testname: watch-configmaps-from-resource-version Description: Ensure that a watch can be opened from a particular resource version in the past and only notifications happening after that resource version are observed. @@ -179,6 +181,7 @@ var _ = SIGDescribe("Watchers", func() { }) /* + Release: v1.11 Testname: watch-configmaps-closed-and-restarted Description: Ensure that a watch can be reopened from the last resource version observed by the previous watch, and it will continue delivering notifications from @@ -244,6 +247,7 @@ var _ = SIGDescribe("Watchers", func() { }) /* + Release: v1.11 Testname: watch-configmaps-label-changed Description: Ensure that a watched object stops meeting the requirements of a watch's selector, the watch will observe a delete, and will not observe @@ -320,8 +324,8 @@ var _ = SIGDescribe("Watchers", func() { }) /* + Release: v1.15 Testname: watch-consistency - Release : v1.15 Description: Ensure that concurrent watches are consistent with each other by initiating an additional watch for events received from the first watch, initiated at the resource version of the event, and checking that all resource versions of all events match. Events are produced from writes on a background goroutine. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/webhook.go b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/webhook.go index 2f3f96ebffcf..923c38bb726c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apimachinery/webhook.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apimachinery/webhook.go @@ -104,7 +104,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, discovery document Description: The admissionregistration.k8s.io API group MUST exists in the /apis discovery document. The admissionregistration.k8s.io/v1 API group/version MUST exists in the /apis discovery document. @@ -183,7 +183,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, deny create Description: Register an admission webhook configuration that admits pod and configmap. Attempts to create non-compliant pods and configmaps, or update/patch compliant pods and configmaps to be non-compliant MUST @@ -198,7 +198,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, deny attach Description: Register an admission webhook configuration that denies connecting to a pod's attach sub-resource. Attempts to attach MUST be denied. @@ -210,7 +210,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, deny custom resource create and delete Description: Register an admission webhook configuration that denies creation, update and deletion of custom resources. Attempts to create, update and delete custom resources MUST be denied. @@ -228,7 +228,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, fail closed Description: Register a webhook with a fail closed policy and without CA bundle so that it cannot be called. Attempt operations that require the admission webhook; all MUST be denied. @@ -240,7 +240,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, ordered mutation Description: Register a mutating webhook configuration with two webhooks that admit configmaps, one that adds a data key if the configmap already has a specific key, and another that adds a key if the key added by @@ -253,7 +253,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, mutation with defaulting Description: Register a mutating webhook that adds an InitContainer to pods. Attempt to create a pod; the InitContainer MUST be added the TerminationMessagePolicy MUST be defaulted. @@ -265,7 +265,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, admission control not allowed on webhook configuration objects Description: Register webhooks that mutate and deny deletion of webhook configuration objects. Attempt to create and delete a webhook configuration object; both operations MUST be allowed and the webhook configuration object @@ -280,7 +280,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, mutate custom resource Description: Register a webhook that mutates a custom resource. Attempt to create custom resource object; the custom resource MUST be mutated. @@ -297,7 +297,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, deny custom resource definition Description: Register a webhook that denies custom resource definition create. Attempt to create a custom resource definition; the create request MUST be denied. @@ -310,7 +310,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, mutate custom resource with different stored version Description: Register a webhook that mutates custom resources on create and update. Register a custom resource definition using v1 as stored version. Create a custom resource. Patch the custom resource definition to use v2 as @@ -329,7 +329,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, mutate custom resource with pruning Description: Register mutating webhooks that adds fields to custom objects. Register a custom resource definition with a schema that includes only one of the data keys added by the webhooks. Attempt to a custom resource; @@ -367,7 +367,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, honor timeout Description: Using a webhook that waits 5 seconds before admitting objects, configure the webhook with combinations of timeouts and failure policy values. Attempt to create a config map with each combination. Requests MUST @@ -401,7 +401,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, update validating webhook Description: Register a validating admission webhook configuration. Update the webhook to not apply to the create operation and attempt to create an object; the webhook MUST NOT deny the create. Patch the webhook to apply to the @@ -496,7 +496,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, update mutating webhook Description: Register a mutating admission webhook configuration. Update the webhook to not apply to the create operation and attempt to create an object; the webhook MUST NOT mutate the object. Patch the webhook to apply to the @@ -569,7 +569,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, list validating webhooks Description: Create 10 validating webhook configurations, all with a label. Attempt to list the webhook configurations matching the label; all the created webhook configurations MUST be present. Attempt to create an @@ -643,7 +643,7 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Admission webhook, list mutating webhooks Description: Create 10 mutating webhook configurations, all with a label. Attempt to list the webhook configurations matching the label; all the created webhook configurations MUST be present. Attempt to create an diff --git a/vendor/k8s.io/kubernetes/test/e2e/apps/daemon_set.go b/vendor/k8s.io/kubernetes/test/e2e/apps/daemon_set.go index 0d49405fb273..d1bfbd7af94a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apps/daemon_set.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apps/daemon_set.go @@ -146,6 +146,7 @@ var _ = SIGDescribe("Daemon set [Serial]", func() { }) /* + Release: v1.10 Testname: DaemonSet-Creation Description: A conformant Kubernetes distribution MUST support the creation of DaemonSets. When a DaemonSet Pod is deleted, the DaemonSet controller MUST create a replacement Pod. @@ -173,6 +174,7 @@ var _ = SIGDescribe("Daemon set [Serial]", func() { }) /* + Release: v1.10 Testname: DaemonSet-NodeSelection Description: A conformant Kubernetes distribution MUST support DaemonSet Pod node selection via label selectors. @@ -273,6 +275,7 @@ var _ = SIGDescribe("Daemon set [Serial]", func() { }) /* + Release: v1.10 Testname: DaemonSet-FailedPodCreation Description: A conformant Kubernetes distribution MUST create new DaemonSet Pods when they fail. */ @@ -352,6 +355,7 @@ var _ = SIGDescribe("Daemon set [Serial]", func() { }) /* + Release: v1.10 Testname: DaemonSet-RollingUpdate Description: A conformant Kubernetes distribution MUST support DaemonSet RollingUpdates. */ @@ -408,6 +412,7 @@ var _ = SIGDescribe("Daemon set [Serial]", func() { }) /* + Release: v1.10 Testname: DaemonSet-Rollback Description: A conformant Kubernetes distribution MUST support automated, minimally disruptive rollback of updates to a DaemonSet. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apps/deployment.go b/vendor/k8s.io/kubernetes/test/e2e/apps/deployment.go index 89053ed1e9d6..1ef9508cd2ce 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apps/deployment.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apps/deployment.go @@ -44,13 +44,13 @@ import ( deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" "k8s.io/kubernetes/test/e2e/framework" e2edeployment "k8s.io/kubernetes/test/e2e/framework/deployment" + e2enode "k8s.io/kubernetes/test/e2e/framework/node" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2ereplicaset "k8s.io/kubernetes/test/e2e/framework/replicaset" e2eresource "k8s.io/kubernetes/test/e2e/framework/resource" e2eservice "k8s.io/kubernetes/test/e2e/framework/service" e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" testutil "k8s.io/kubernetes/test/utils" - "k8s.io/utils/integer" utilpointer "k8s.io/utils/pointer" ) @@ -84,6 +84,7 @@ var _ = SIGDescribe("Deployment", func() { testDeleteDeployment(f) }) /* + Release: v1.12 Testname: Deployment RollingUpdate Description: A conformant Kubernetes distribution MUST support the Deployment with RollingUpdate strategy. */ @@ -91,6 +92,7 @@ var _ = SIGDescribe("Deployment", func() { testRollingUpdateDeployment(f) }) /* + Release: v1.12 Testname: Deployment Recreate Description: A conformant Kubernetes distribution MUST support the Deployment with Recreate strategy. */ @@ -98,6 +100,7 @@ var _ = SIGDescribe("Deployment", func() { testRecreateDeployment(f) }) /* + Release: v1.12 Testname: Deployment RevisionHistoryLimit Description: A conformant Kubernetes distribution MUST clean up Deployment's ReplicaSets based on the Deployment's `.spec.revisionHistoryLimit`. @@ -106,6 +109,7 @@ var _ = SIGDescribe("Deployment", func() { testDeploymentCleanUpPolicy(f) }) /* + Release: v1.12 Testname: Deployment Rollover Description: A conformant Kubernetes distribution MUST support Deployment rollover, i.e. allow arbitrary number of changes to desired state during rolling update @@ -121,6 +125,7 @@ var _ = SIGDescribe("Deployment", func() { testDeploymentsControllerRef(f) }) /* + Release: v1.12 Testname: Deployment Proportional Scaling Description: A conformant Kubernetes distribution MUST support Deployment proportional scaling, i.e. proportionally scale a Deployment's ReplicaSets @@ -130,8 +135,10 @@ var _ = SIGDescribe("Deployment", func() { testProportionalScalingDeployment(f) }) ginkgo.It("should not disrupt a cloud load-balancer's connectivity during rollout", func() { - e2eskipper.SkipUnlessNodeCountIsAtLeast(2) e2eskipper.SkipUnlessProviderIs("aws", "azure", "gce", "gke") + nodes, err := e2enode.GetReadySchedulableNodes(c) + framework.ExpectNoError(err) + e2eskipper.SkipUnlessAtLeast(len(nodes.Items), 3, "load-balancer test requires at least 3 schedulable nodes") testRollingUpdateDeploymentWithLocalTrafficLoadBalancer(f) }) // TODO: add tests that cover deployment.Spec.MinReadySeconds once we solved clock-skew issues @@ -553,7 +560,7 @@ func testIterativeDeployments(f *framework.Framework) { // trigger a new deployment framework.Logf("%02d: triggering a new rollout for deployment %q", i, deployment.Name) deployment, err = e2edeployment.UpdateDeploymentWithRetries(c, ns, deployment.Name, func(update *appsv1.Deployment) { - newEnv := v1.EnvVar{Name: "A", Value: fmt.Sprintf("%d", i)} + newEnv := v1.EnvVar{Name: fmt.Sprintf("A%d", i), Value: fmt.Sprintf("%d", i)} update.Spec.Template.Spec.Containers[0].Env = append(update.Spec.Template.Spec.Containers[0].Env, newEnv) randomScale(update, i) }) @@ -874,7 +881,7 @@ func testRollingUpdateDeploymentWithLocalTrafficLoadBalancer(f *framework.Framew name := "test-rolling-update-with-lb" framework.Logf("Creating Deployment %q", name) podLabels := map[string]string{"name": name} - replicas := int32(integer.IntMin(5, framework.TestContext.CloudConfig.NumNodes)) + replicas := int32(3) d := e2edeployment.NewDeployment(name, replicas, podLabels, AgnhostImageName, AgnhostImage, appsv1.RollingUpdateDeploymentStrategyType) // NewDeployment assigned the same value to both d.Spec.Selector and // d.Spec.Template.Labels, so mutating the one would mutate the other. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apps/job.go b/vendor/k8s.io/kubernetes/test/e2e/apps/job.go index e7006a81dec3..9c9c23fe6ea1 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apps/job.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apps/job.go @@ -92,7 +92,7 @@ var _ = SIGDescribe("Job", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Jobs, completion after task failure Description: Explicitly cause the tasks to fail once initially. After restarting, the Job MUST execute to completion. @@ -148,7 +148,7 @@ var _ = SIGDescribe("Job", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: Jobs, active pods, graceful termination Description: Create a job. Ensure the active pods reflect paralellism in the namespace and delete the job. Job MUST be deleted successfully. */ @@ -172,7 +172,7 @@ var _ = SIGDescribe("Job", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Jobs, orphan pods, re-adoption Description: Create a parallel job. The number of Pods MUST equal the level of parallelism. Orphan a Pod by modifying its owner reference. The Job MUST re-adopt the orphan pod. diff --git a/vendor/k8s.io/kubernetes/test/e2e/apps/rc.go b/vendor/k8s.io/kubernetes/test/e2e/apps/rc.go index 08573c293a0b..c2fc954d6828 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apps/rc.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apps/rc.go @@ -57,7 +57,7 @@ var _ = SIGDescribe("ReplicationController", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Replication Controller, run basic image Description: Replication Controller MUST create a Pod with Basic Image and MUST run the service with the provided image. Image MUST be tested by dialing into the service listening through TCP, UDP and HTTP. */ @@ -73,7 +73,7 @@ var _ = SIGDescribe("ReplicationController", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: Replication Controller, check for issues like exceeding allocated quota Description: Attempt to create a Replication Controller with pods exceeding the namespace quota. The creation MUST fail */ @@ -82,7 +82,7 @@ var _ = SIGDescribe("ReplicationController", func() { }) /* - Release : v1.13 + Release: v1.13 Testname: Replication Controller, adopt matching pods Description: An ownerless Pod is created, then a Replication Controller (RC) is created whose label selector will match the Pod. The RC MUST either adopt the Pod or delete and replace it with a new Pod */ @@ -91,7 +91,7 @@ var _ = SIGDescribe("ReplicationController", func() { }) /* - Release : v1.13 + Release: v1.13 Testname: Replication Controller, release pods Description: A Replication Controller (RC) is created, and its Pods are created. When the labels on one of the Pods change to no longer match the RC's label selector, the RC MUST release the Pod and update the Pod's owner references. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/apps/replica_set.go b/vendor/k8s.io/kubernetes/test/e2e/apps/replica_set.go index 9b01d8b32079..f08df5653f0c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apps/replica_set.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apps/replica_set.go @@ -87,7 +87,7 @@ var _ = SIGDescribe("ReplicaSet", func() { f := framework.NewDefaultFramework("replicaset") /* - Release : v1.9 + Release: v1.9 Testname: Replica Set, run basic image Description: Create a ReplicaSet with a Pod and a single Container. Make sure that the Pod is running. Pod SHOULD send a valid response when queried. */ @@ -107,7 +107,7 @@ var _ = SIGDescribe("ReplicaSet", func() { }) /* - Release : v1.13 + Release: v1.13 Testname: Replica Set, adopt matching pods and release non matching pods Description: A Pod is created, then a Replica Set (RS) whose label selector will match the Pod. The RS MUST either adopt the Pod or delete and replace it with a new Pod. When the labels on one of the Pods owned by the RS change to no longer match the RS's label selector, the RS MUST release the Pod and update the Pod's owner references */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/apps/statefulset.go b/vendor/k8s.io/kubernetes/test/e2e/apps/statefulset.go index 29bf7d1dbb5d..b136689fb1ca 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/apps/statefulset.go +++ b/vendor/k8s.io/kubernetes/test/e2e/apps/statefulset.go @@ -289,7 +289,7 @@ var _ = SIGDescribe("StatefulSet", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: StatefulSet, Rolling Update Description: StatefulSet MUST support the RollingUpdate strategy to automatically replace Pods one at a time when the Pod template changes. The StatefulSet's status MUST indicate the CurrentRevision and UpdateRevision. If the template is changed to match a prior revision, StatefulSet MUST detect this as a rollback instead of creating a new revision. This test does not depend on a preexisting default StorageClass or a dynamic provisioner. */ @@ -300,7 +300,7 @@ var _ = SIGDescribe("StatefulSet", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: StatefulSet, Rolling Update with Partition Description: StatefulSet's RollingUpdate strategy MUST support the Partition parameter for canaries and phased rollouts. If a Pod is deleted while a rolling update is in progress, StatefulSet MUST restore the Pod without violating the Partition. This test does not depend on a preexisting default StorageClass or a dynamic provisioner. */ @@ -570,7 +570,7 @@ var _ = SIGDescribe("StatefulSet", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: StatefulSet, Scaling Description: StatefulSet MUST create Pods in ascending order by ordinal index when scaling up, and delete Pods in descending order when scaling down. Scaling up or down MUST pause if any Pods belonging to the StatefulSet are unhealthy. This test does not depend on a preexisting default StorageClass or a dynamic provisioner. */ @@ -680,7 +680,7 @@ var _ = SIGDescribe("StatefulSet", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: StatefulSet, Burst Scaling Description: StatefulSet MUST support the Parallel PodManagementPolicy for burst scaling. This test does not depend on a preexisting default StorageClass or a dynamic provisioner. */ @@ -722,7 +722,7 @@ var _ = SIGDescribe("StatefulSet", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: StatefulSet, Recreate Failed Pod Description: StatefulSet MUST delete and recreate Pods it owns that go into a Failed state, such as when they are rejected or evicted by a Node. This test does not depend on a preexisting default StorageClass or a dynamic provisioner. */ @@ -830,7 +830,7 @@ var _ = SIGDescribe("StatefulSet", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: StatefulSet resource Replica scaling Description: Create a StatefulSet resource. Newly created StatefulSet resource MUST have a scale of one. @@ -981,18 +981,16 @@ func (z *zookeeperTester) deploy(ns string) *appsv1.StatefulSet { func (z *zookeeperTester) write(statefulPodIndex int, kv map[string]string) { name := fmt.Sprintf("%v-%d", z.ss.Name, statefulPodIndex) - ns := fmt.Sprintf("--namespace=%v", z.ss.Namespace) for k, v := range kv { cmd := fmt.Sprintf("/opt/zookeeper/bin/zkCli.sh create /%v %v", k, v) - framework.Logf(framework.RunKubectlOrDie(z.ss.Namespace, "exec", ns, name, "--", "/bin/sh", "-c", cmd)) + framework.Logf(framework.RunKubectlOrDie(z.ss.Namespace, "exec", name, "--", "/bin/sh", "-c", cmd)) } } func (z *zookeeperTester) read(statefulPodIndex int, key string) string { name := fmt.Sprintf("%v-%d", z.ss.Name, statefulPodIndex) - ns := fmt.Sprintf("--namespace=%v", z.ss.Namespace) cmd := fmt.Sprintf("/opt/zookeeper/bin/zkCli.sh get /%v", key) - return lastLine(framework.RunKubectlOrDie(z.ss.Namespace, "exec", ns, name, "--", "/bin/sh", "-c", cmd)) + return lastLine(framework.RunKubectlOrDie(z.ss.Namespace, "exec", name, "--", "/bin/sh", "-c", cmd)) } type mysqlGaleraTester struct { @@ -1009,7 +1007,7 @@ func (m *mysqlGaleraTester) mysqlExec(cmd, ns, podName string) string { // TODO: Find a readiness probe for mysql that guarantees writes will // succeed and ditch retries. Current probe only reads, so there's a window // for a race. - return kubectlExecWithRetries(ns, fmt.Sprintf("--namespace=%v", ns), "exec", podName, "--", "/bin/sh", "-c", cmd) + return kubectlExecWithRetries(ns, "exec", podName, "--", "/bin/sh", "-c", cmd) } func (m *mysqlGaleraTester) deploy(ns string) *appsv1.StatefulSet { @@ -1049,7 +1047,7 @@ func (m *redisTester) name() string { func (m *redisTester) redisExec(cmd, ns, podName string) string { cmd = fmt.Sprintf("/opt/redis/redis-cli -h %v %v", podName, cmd) - return framework.RunKubectlOrDie(ns, fmt.Sprintf("--namespace=%v", ns), "exec", podName, "--", "/bin/sh", "-c", cmd) + return framework.RunKubectlOrDie(ns, "exec", podName, "--", "/bin/sh", "-c", cmd) } func (m *redisTester) deploy(ns string) *appsv1.StatefulSet { @@ -1080,7 +1078,7 @@ func (c *cockroachDBTester) name() string { func (c *cockroachDBTester) cockroachDBExec(cmd, ns, podName string) string { cmd = fmt.Sprintf("/cockroach/cockroach sql --insecure --host %s.cockroachdb -e \"%v\"", podName, cmd) - return framework.RunKubectlOrDie(ns, fmt.Sprintf("--namespace=%v", ns), "exec", podName, "--", "/bin/sh", "-c", cmd) + return framework.RunKubectlOrDie(ns, "exec", podName, "--", "/bin/sh", "-c", cmd) } func (c *cockroachDBTester) deploy(ns string) *appsv1.StatefulSet { diff --git a/vendor/k8s.io/kubernetes/test/e2e/auth/BUILD b/vendor/k8s.io/kubernetes/test/e2e/auth/BUILD index 2fd97e9515a9..9ae0dceac48e 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/auth/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/auth/BUILD @@ -3,7 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", srcs = [ - "audit.go", "certificates.go", "framework.go", "metadata_concealment.go", @@ -19,16 +18,12 @@ go_library( "//pkg/security/podsecuritypolicy/seccomp:go_default_library", "//pkg/security/podsecuritypolicy/util:go_default_library", "//plugin/pkg/admission/serviceaccount:go_default_library", - "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/authentication/v1:go_default_library", "//staging/src/k8s.io/api/batch/v1:go_default_library", "//staging/src/k8s.io/api/certificates/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/policy/v1beta1:go_default_library", "//staging/src/k8s.io/api/rbac/v1:go_default_library", - "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library", - "//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library", - "//staging/src/k8s.io/apiextensions-apiserver/test/integration/fixtures:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", @@ -37,8 +32,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/apis/audit/v1:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/certificates/v1:go_default_library", @@ -46,7 +39,6 @@ go_library( "//staging/src/k8s.io/client-go/util/cert:go_default_library", "//test/e2e/framework:go_default_library", "//test/e2e/framework/auth:go_default_library", - "//test/e2e/framework/deployment:go_default_library", "//test/e2e/framework/job:go_default_library", "//test/e2e/framework/kubectl:go_default_library", "//test/e2e/framework/node:go_default_library", @@ -54,7 +46,6 @@ go_library( "//test/e2e/framework/skipper:go_default_library", "//test/utils:go_default_library", "//test/utils/image:go_default_library", - "//vendor/github.com/evanphx/json-patch:go_default_library", "//vendor/github.com/onsi/ginkgo:go_default_library", "//vendor/github.com/onsi/gomega:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library", diff --git a/vendor/k8s.io/kubernetes/test/e2e/auth/audit.go b/vendor/k8s.io/kubernetes/test/e2e/auth/audit.go deleted file mode 100644 index 94ba76e185d4..000000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/auth/audit.go +++ /dev/null @@ -1,751 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package auth - -import ( - "context" - "encoding/json" - "fmt" - "strings" - "time" - - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/api/core/v1" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - apiextensionclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - "k8s.io/apiextensions-apiserver/test/integration/fixtures" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" - auditinternal "k8s.io/apiserver/pkg/apis/audit" - auditv1 "k8s.io/apiserver/pkg/apis/audit/v1" - clientset "k8s.io/client-go/kubernetes" - restclient "k8s.io/client-go/rest" - "k8s.io/kubernetes/test/e2e/framework" - e2eauth "k8s.io/kubernetes/test/e2e/framework/auth" - e2edeployment "k8s.io/kubernetes/test/e2e/framework/deployment" - e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" - "k8s.io/kubernetes/test/utils" - imageutils "k8s.io/kubernetes/test/utils/image" - - jsonpatch "github.com/evanphx/json-patch" - "github.com/onsi/ginkgo" -) - -var ( - watchTestTimeout int64 = 1 - auditTestUser = "kubecfg" - - crd = fixtures.NewRandomNameV1CustomResourceDefinition(apiextensionsv1.ClusterScoped) - crdName = strings.SplitN(crd.Name, ".", 2)[0] - crdNamespace = strings.SplitN(crd.Name, ".", 2)[1] - - watchOptions = metav1.ListOptions{TimeoutSeconds: &watchTestTimeout} - patch, _ = json.Marshal(jsonpatch.Patch{}) -) - -// TODO: Get rid of [DisabledForLargeClusters] when feature request #53455 is ready. -// Marked as flaky until a reliable method for collecting server-side audit logs is available. See http://issue.k8s.io/74745#issuecomment-474052439 -var _ = SIGDescribe("Advanced Audit [DisabledForLargeClusters][Flaky]", func() { - f := framework.NewDefaultFramework("audit") - var namespace string - ginkgo.BeforeEach(func() { - e2eskipper.SkipUnlessProviderIs("gce") - namespace = f.Namespace.Name - }) - - ginkgo.It("should audit API calls to create, get, update, patch, delete, list, watch pods.", func() { - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "audit-pod", - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{{ - Name: "pause", - Image: imageutils.GetPauseImageName(), - }}, - }, - } - updatePod := func(pod *v1.Pod) {} - - f.PodClient().CreateSync(pod) - - _, err := f.PodClient().Get(context.TODO(), pod.Name, metav1.GetOptions{}) - framework.ExpectNoError(err, "failed to get audit-pod") - - podChan, err := f.PodClient().Watch(context.TODO(), watchOptions) - framework.ExpectNoError(err, "failed to create watch for pods") - podChan.Stop() - - f.PodClient().Update(pod.Name, updatePod) - - _, err = f.PodClient().List(context.TODO(), metav1.ListOptions{}) - framework.ExpectNoError(err, "failed to list pods") - - _, err = f.PodClient().Patch(context.TODO(), pod.Name, types.JSONPatchType, patch, metav1.PatchOptions{}) - framework.ExpectNoError(err, "failed to patch pod") - - f.PodClient().DeleteSync(pod.Name, metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout) - - expectEvents(f, []utils.AuditEvent{ - { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods", namespace), - Verb: "create", - Code: 201, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods/audit-pod", namespace), - Verb: "get", - Code: 200, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods", namespace), - Verb: "list", - Code: 200, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseStarted, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods?timeout=%ds&timeoutSeconds=%d&watch=true", namespace, watchTestTimeout, watchTestTimeout), - Verb: "watch", - Code: 200, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods?timeout=%ds&timeoutSeconds=%d&watch=true", namespace, watchTestTimeout, watchTestTimeout), - Verb: "watch", - Code: 200, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods/audit-pod", namespace), - Verb: "update", - Code: 200, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods/audit-pod", namespace), - Verb: "patch", - Code: 200, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods/audit-pod", namespace), - Verb: "delete", - Code: 200, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, - }) - }) - - ginkgo.It("should audit API calls to create, get, update, patch, delete, list, watch deployments.", func() { - podLabels := map[string]string{"name": "audit-deployment-pod"} - d := e2edeployment.NewDeployment("audit-deployment", int32(1), podLabels, "agnhost", imageutils.GetE2EImage(imageutils.Agnhost), appsv1.RecreateDeploymentStrategyType) - - _, err := f.ClientSet.AppsV1().Deployments(namespace).Create(context.TODO(), d, metav1.CreateOptions{}) - framework.ExpectNoError(err, "failed to create audit-deployment") - - _, err = f.ClientSet.AppsV1().Deployments(namespace).Get(context.TODO(), d.Name, metav1.GetOptions{}) - framework.ExpectNoError(err, "failed to get audit-deployment") - - deploymentChan, err := f.ClientSet.AppsV1().Deployments(namespace).Watch(context.TODO(), watchOptions) - framework.ExpectNoError(err, "failed to create watch for deployments") - deploymentChan.Stop() - - _, err = f.ClientSet.AppsV1().Deployments(namespace).Update(context.TODO(), d, metav1.UpdateOptions{}) - framework.ExpectNoError(err, "failed to update audit-deployment") - - _, err = f.ClientSet.AppsV1().Deployments(namespace).Patch(context.TODO(), d.Name, types.JSONPatchType, patch, metav1.PatchOptions{}) - framework.ExpectNoError(err, "failed to patch deployment") - - _, err = f.ClientSet.AppsV1().Deployments(namespace).List(context.TODO(), metav1.ListOptions{}) - framework.ExpectNoError(err, "failed to create list deployments") - - err = f.ClientSet.AppsV1().Deployments(namespace).Delete(context.TODO(), "audit-deployment", metav1.DeleteOptions{}) - framework.ExpectNoError(err, "failed to delete deployments") - - expectEvents(f, []utils.AuditEvent{ - { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments", namespace), - Verb: "create", - Code: 201, - User: auditTestUser, - Resource: "deployments", - Namespace: namespace, - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments/audit-deployment", namespace), - Verb: "get", - Code: 200, - User: auditTestUser, - Resource: "deployments", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments", namespace), - Verb: "list", - Code: 200, - User: auditTestUser, - Resource: "deployments", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseStarted, - RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments?timeout=%ds&timeoutSeconds=%d&watch=true", namespace, watchTestTimeout, watchTestTimeout), - Verb: "watch", - Code: 200, - User: auditTestUser, - Resource: "deployments", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments?timeout=%ds&timeoutSeconds=%d&watch=true", namespace, watchTestTimeout, watchTestTimeout), - Verb: "watch", - Code: 200, - User: auditTestUser, - Resource: "deployments", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments/audit-deployment", namespace), - Verb: "update", - Code: 200, - User: auditTestUser, - Resource: "deployments", - Namespace: namespace, - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments/audit-deployment", namespace), - Verb: "patch", - Code: 200, - User: auditTestUser, - Resource: "deployments", - Namespace: namespace, - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments/audit-deployment", namespace), - Verb: "delete", - Code: 200, - User: auditTestUser, - Resource: "deployments", - Namespace: namespace, - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, - }) - }) - - ginkgo.It("should audit API calls to create, get, update, patch, delete, list, watch configmaps.", func() { - configMap := &v1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "audit-configmap", - }, - Data: map[string]string{ - "map-key": "map-value", - }, - } - - _, err := f.ClientSet.CoreV1().ConfigMaps(namespace).Create(context.TODO(), configMap, metav1.CreateOptions{}) - framework.ExpectNoError(err, "failed to create audit-configmap") - - _, err = f.ClientSet.CoreV1().ConfigMaps(namespace).Get(context.TODO(), configMap.Name, metav1.GetOptions{}) - framework.ExpectNoError(err, "failed to get audit-configmap") - - configMapChan, err := f.ClientSet.CoreV1().ConfigMaps(namespace).Watch(context.TODO(), watchOptions) - framework.ExpectNoError(err, "failed to create watch for config maps") - configMapChan.Stop() - - _, err = f.ClientSet.CoreV1().ConfigMaps(namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{}) - framework.ExpectNoError(err, "failed to update audit-configmap") - - _, err = f.ClientSet.CoreV1().ConfigMaps(namespace).Patch(context.TODO(), configMap.Name, types.JSONPatchType, patch, metav1.PatchOptions{}) - framework.ExpectNoError(err, "failed to patch configmap") - - _, err = f.ClientSet.CoreV1().ConfigMaps(namespace).List(context.TODO(), metav1.ListOptions{}) - framework.ExpectNoError(err, "failed to list config maps") - - err = f.ClientSet.CoreV1().ConfigMaps(namespace).Delete(context.TODO(), configMap.Name, metav1.DeleteOptions{}) - framework.ExpectNoError(err, "failed to delete audit-configmap") - - expectEvents(f, []utils.AuditEvent{ - { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/configmaps", namespace), - Verb: "create", - Code: 201, - User: auditTestUser, - Resource: "configmaps", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/configmaps/audit-configmap", namespace), - Verb: "get", - Code: 200, - User: auditTestUser, - Resource: "configmaps", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/configmaps", namespace), - Verb: "list", - Code: 200, - User: auditTestUser, - Resource: "configmaps", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseStarted, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/configmaps?timeout=%ds&timeoutSeconds=%d&watch=true", namespace, watchTestTimeout, watchTestTimeout), - Verb: "watch", - Code: 200, - User: auditTestUser, - Resource: "configmaps", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/configmaps?timeout=%ds&timeoutSeconds=%d&watch=true", namespace, watchTestTimeout, watchTestTimeout), - Verb: "watch", - Code: 200, - User: auditTestUser, - Resource: "configmaps", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/configmaps/audit-configmap", namespace), - Verb: "update", - Code: 200, - User: auditTestUser, - Resource: "configmaps", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/configmaps/audit-configmap", namespace), - Verb: "patch", - Code: 200, - User: auditTestUser, - Resource: "configmaps", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/configmaps/audit-configmap", namespace), - Verb: "delete", - Code: 200, - User: auditTestUser, - Resource: "configmaps", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, - }) - }) - - ginkgo.It("should audit API calls to create, get, update, patch, delete, list, watch secrets.", func() { - secret := &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "audit-secret", - }, - Data: map[string][]byte{ - "top-secret": []byte("foo-bar"), - }, - } - _, err := f.ClientSet.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{}) - framework.ExpectNoError(err, "failed to create audit-secret") - - _, err = f.ClientSet.CoreV1().Secrets(namespace).Get(context.TODO(), secret.Name, metav1.GetOptions{}) - framework.ExpectNoError(err, "failed to get audit-secret") - - secretChan, err := f.ClientSet.CoreV1().Secrets(namespace).Watch(context.TODO(), watchOptions) - framework.ExpectNoError(err, "failed to create watch for secrets") - secretChan.Stop() - - _, err = f.ClientSet.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}) - framework.ExpectNoError(err, "failed to update audit-secret") - - _, err = f.ClientSet.CoreV1().Secrets(namespace).Patch(context.TODO(), secret.Name, types.JSONPatchType, patch, metav1.PatchOptions{}) - framework.ExpectNoError(err, "failed to patch secret") - - _, err = f.ClientSet.CoreV1().Secrets(namespace).List(context.TODO(), metav1.ListOptions{}) - framework.ExpectNoError(err, "failed to list secrets") - - err = f.ClientSet.CoreV1().Secrets(namespace).Delete(context.TODO(), secret.Name, metav1.DeleteOptions{}) - framework.ExpectNoError(err, "failed to delete audit-secret") - - expectEvents(f, []utils.AuditEvent{ - { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/secrets", namespace), - Verb: "create", - Code: 201, - User: auditTestUser, - Resource: "secrets", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/secrets/audit-secret", namespace), - Verb: "get", - Code: 200, - User: auditTestUser, - Resource: "secrets", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/secrets", namespace), - Verb: "list", - Code: 200, - User: auditTestUser, - Resource: "secrets", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseStarted, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/secrets?timeout=%ds&timeoutSeconds=%d&watch=true", namespace, watchTestTimeout, watchTestTimeout), - Verb: "watch", - Code: 200, - User: auditTestUser, - Resource: "secrets", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/secrets?timeout=%ds&timeoutSeconds=%d&watch=true", namespace, watchTestTimeout, watchTestTimeout), - Verb: "watch", - Code: 200, - User: auditTestUser, - Resource: "secrets", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/secrets/audit-secret", namespace), - Verb: "update", - Code: 200, - User: auditTestUser, - Resource: "secrets", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/secrets/audit-secret", namespace), - Verb: "patch", - Code: 200, - User: auditTestUser, - Resource: "secrets", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/secrets/audit-secret", namespace), - Verb: "delete", - Code: 200, - User: auditTestUser, - Resource: "secrets", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, - }) - }) - - ginkgo.It("should audit API calls to create and delete custom resource definition.", func() { - config, err := framework.LoadConfig() - framework.ExpectNoError(err, "failed to load config") - apiExtensionClient, err := apiextensionclientset.NewForConfig(config) - framework.ExpectNoError(err, "failed to initialize apiExtensionClient") - - crd, err = fixtures.CreateNewV1CustomResourceDefinition(crd, apiExtensionClient, f.DynamicClient) - framework.ExpectNoError(err, "failed to create custom resource definition") - err = fixtures.DeleteV1CustomResourceDefinition(crd, apiExtensionClient) - framework.ExpectNoError(err, "failed to delete custom resource definition") - - expectEvents(f, []utils.AuditEvent{ - { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: "/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions", - Verb: "create", - Code: 201, - User: auditTestUser, - Resource: "customresourcedefinitions", - RequestObject: true, - ResponseObject: true, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/%s/v1beta1/%s", crdNamespace, crdName), - Verb: "create", - Code: 201, - User: auditTestUser, - Resource: crdName, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelRequestResponse, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/%s", crd.Name), - Verb: "delete", - Code: 200, - User: auditTestUser, - Resource: "customresourcedefinitions", - RequestObject: false, - ResponseObject: true, - AuthorizeDecision: "allow", - }, { - Level: auditinternal.LevelMetadata, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/apis/%s/v1beta1/%s/setup-instance", crdNamespace, crdName), - Verb: "delete", - Code: 200, - User: auditTestUser, - Resource: crdName, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, - }) - }) - - // test authorizer annotations, RBAC is required. - ginkgo.It("should audit API calls to get a pod with unauthorized user.", func() { - if !e2eauth.IsRBACEnabled(f.ClientSet.RbacV1()) { - e2eskipper.Skipf("RBAC not enabled.") - } - - ginkgo.By("Creating a kubernetes client that impersonates an unauthorized anonymous user") - config, err := framework.LoadConfig() - framework.ExpectNoError(err) - config.Impersonate = restclient.ImpersonationConfig{ - UserName: "system:anonymous", - Groups: []string{"system:unauthenticated"}, - } - anonymousClient, err := clientset.NewForConfig(config) - framework.ExpectNoError(err) - - _, err = anonymousClient.CoreV1().Pods(namespace).Get(context.TODO(), "another-audit-pod", metav1.GetOptions{}) - expectForbidden(err) - - expectEvents(f, []utils.AuditEvent{ - { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods/another-audit-pod", namespace), - Verb: "get", - Code: 403, - User: auditTestUser, - ImpersonatedUser: "system:anonymous", - ImpersonatedGroups: "system:unauthenticated", - Resource: "pods", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "forbid", - }, - }) - }) - - ginkgo.It("should list pods as impersonated user.", func() { - ginkgo.By("Creating a kubernetes client that impersonates an authorized user") - config, err := framework.LoadConfig() - framework.ExpectNoError(err) - config.Impersonate = restclient.ImpersonationConfig{ - UserName: "superman", - Groups: []string{"system:masters"}, - } - impersonatedClient, err := clientset.NewForConfig(config) - framework.ExpectNoError(err) - - _, err = impersonatedClient.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{}) - framework.ExpectNoError(err, "failed to list pods") - - expectEvents(f, []utils.AuditEvent{ - { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods", namespace), - Verb: "list", - Code: 200, - User: auditTestUser, - ImpersonatedUser: "superman", - ImpersonatedGroups: "system:masters", - Resource: "pods", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "allow", - }, - }) - }) - -}) - -func expectEvents(f *framework.Framework, expectedEvents []utils.AuditEvent) { - // The default flush timeout is 30 seconds, therefore it should be enough to retry once - // to find all expected events. However, we're waiting for 5 minutes to avoid flakes. - pollingInterval := 30 * time.Second - pollingTimeout := 5 * time.Minute - err := wait.Poll(pollingInterval, pollingTimeout, func() (bool, error) { - // Fetch the log stream. - stream, err := f.ClientSet.CoreV1().RESTClient().Get().AbsPath("/logs/kube-apiserver-audit.log").Stream(context.TODO()) - if err != nil { - return false, err - } - defer stream.Close() - missingReport, err := utils.CheckAuditLines(stream, expectedEvents, auditv1.SchemeGroupVersion) - if err != nil { - framework.Logf("Failed to observe audit events: %v", err) - } else if len(missingReport.MissingEvents) > 0 { - framework.Logf(missingReport.String()) - } - return len(missingReport.MissingEvents) == 0, nil - }) - framework.ExpectNoError(err, "after %v failed to observe audit events", pollingTimeout) -} diff --git a/vendor/k8s.io/kubernetes/test/e2e/auth/pod_security_policy.go b/vendor/k8s.io/kubernetes/test/e2e/auth/pod_security_policy.go index a1ca9c75f40f..70c363f19322 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/auth/pod_security_policy.go +++ b/vendor/k8s.io/kubernetes/test/e2e/auth/pod_security_policy.go @@ -52,7 +52,6 @@ var _ = SIGDescribe("PodSecurityPolicy [Feature:PodSecurityPolicy]", func() { var c clientset.Interface var ns string // Test namespace, for convenience ginkgo.BeforeEach(func() { - e2eskipper.Skipf("This test should always be skipped for us, but occasionally PSP is on!") if !framework.IsPodSecurityPolicyEnabled(f.ClientSet) { framework.Failf("PodSecurityPolicy not enabled") return diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/configmap.go b/vendor/k8s.io/kubernetes/test/e2e/common/configmap.go index 64a479709afd..95d4f3249a47 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/configmap.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/configmap.go @@ -35,7 +35,7 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { f := framework.NewDefaultFramework("configmap") /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap, from environment field Description: Create a Pod with an environment variable value set using a value from ConfigMap. A ConfigMap value MUST be accessible in the container environment. */ @@ -128,7 +128,7 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { }) /* - Release : v1.14 + Release: v1.14 Testname: ConfigMap, with empty-key Description: Attempt to create a ConfigMap with an empty key. The creation MUST fail. */ @@ -158,7 +158,7 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: ConfigMap lifecycle Description: Attempt to create a ConfigMap. Patch the created ConfigMap. Fetching the ConfigMap MUST reflect changes. By fetching all the ConfigMaps via a Label selector it MUST find the ConfigMap by it's static label and updated value. The ConfigMap must be deleted by Collection. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/configmap_volume.go b/vendor/k8s.io/kubernetes/test/e2e/common/configmap_volume.go index 549f0a514eea..77881c368ea9 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/configmap_volume.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/configmap_volume.go @@ -23,7 +23,7 @@ import ( "github.com/onsi/ginkgo" "github.com/onsi/gomega" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" @@ -37,7 +37,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { f := framework.NewDefaultFramework("configmap") /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, without mapping Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The data content of the file MUST be readable and verified and file modes MUST default to 0x644. */ @@ -46,7 +46,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, without mapping, volume mode set Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. File mode is changed to a custom value of '0x400'. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The data content of the file MUST be readable and verified and file modes MUST be set to the custom value of '0x400' This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -64,7 +64,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, without mapping, non-root user Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. Pod is run as a non-root user with uid=1000. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The file on the volume MUST have file mode set to default value of 0x644. */ @@ -79,7 +79,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, with mapping Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. Files are mapped to a path in the volume. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The data content of the file MUST be readable and verified and file modes MUST default to 0x644. */ @@ -88,7 +88,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, with mapping, volume mode set Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. Files are mapped to a path in the volume. File mode is changed to a custom value of '0x400'. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The data content of the file MUST be readable and verified and file modes MUST be set to the custom value of '0x400' This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -99,7 +99,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, with mapping, non-root user Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. Files are mapped to a path in the volume. Pod is run as a non-root user with uid=1000. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The file on the volume MUST have file mode set to default value of 0x644. */ @@ -114,7 +114,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, update Description: The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount that is mapped to custom path in the Pod. When the ConfigMap is updated the change to the config map MUST be verified by reading the content from the mounted file in the Pod. */ @@ -293,7 +293,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, create, update and delete Description: The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount that is mapped to custom path in the Pod. When the config map is updated the change to the config map MUST be verified by reading the content from the mounted file in the Pod. Also when the item(file) is deleted from the map that MUST result in a error reading that item(file). */ @@ -476,7 +476,7 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: ConfigMap Volume, multiple volume maps Description: The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount that is mapped to multiple paths in the Pod. The content MUST be accessible from all the mapped volume mounts. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/container_probe.go b/vendor/k8s.io/kubernetes/test/e2e/common/container_probe.go index 72ebcd5f548d..469ffe8268ea 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/container_probe.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/container_probe.go @@ -56,7 +56,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pod readiness probe, with initial delay Description: Create a Pod that is configured with a initial delay set on the readiness probe. Check the Pod Start time to compare to the initial delay. The Pod MUST be ready only after the specified initial delay. */ @@ -89,7 +89,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pod readiness probe, failure Description: Create a Pod with a readiness probe that fails consistently. When this Pod is created, then the Pod MUST never be ready, never be running and restart count MUST be zero. @@ -115,7 +115,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pod liveness probe, using local file, restart Description: Create a Pod with liveness probe that uses ExecAction handler to cat /temp/health file. The Container deletes the file /temp/health after 10 second, triggering liveness probe to fail. The Pod MUST now be killed and restarted incrementing restart count to 1. */ @@ -131,7 +131,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pod liveness probe, using local file, no restart Description: Pod is created with liveness probe that uses 'exec' command to cat /temp/health file. Liveness probe MUST not fail to check health and the restart count should remain 0. */ @@ -147,7 +147,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pod liveness probe, using http endpoint, restart Description: A Pod is created with liveness probe on http endpoint /healthz. The http handler on the /healthz will return a http error after 10 seconds since the Pod is started. This MUST result in liveness check failure. The Pod MUST now be killed and restarted incrementing restart count to 1. */ @@ -162,7 +162,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.18 + Release: v1.18 Testname: Pod liveness probe, using tcp socket, no restart Description: A Pod is created with liveness probe on tcp socket 8080. The http handler on port 8080 will return http errors after 10 seconds, but the socket will remain open. Liveness probe MUST not fail to check health and the restart count should remain 0. */ @@ -177,7 +177,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pod liveness probe, using http endpoint, multiple restarts (slow) Description: A Pod is created with liveness probe on http endpoint /healthz. The http handler on the /healthz will return a http error after 10 seconds since the Pod is started. This MUST result in liveness check failure. The Pod MUST now be killed and restarted incrementing restart count to 1. The liveness probe must fail again after restart once the http handler for /healthz enpoind on the Pod returns an http error after 10 seconds from the start. Restart counts MUST increment everytime health check fails, measure upto 5 restart. */ @@ -192,7 +192,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pod liveness probe, using http endpoint, failure Description: A Pod is created with liveness probe on http endpoint '/'. Liveness probe on this endpoint will not fail. When liveness probe does not fail then the restart count MUST remain zero. */ @@ -208,7 +208,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pod liveness probe, docker exec, restart Description: A Pod is created with liveness probe with a Exec action on the Pod. If the liveness probe call does not return within the timeout specified, liveness probe MUST restart the Pod. */ @@ -227,7 +227,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.14 + Release: v1.14 Testname: Pod http liveness probe, redirected to a local address Description: A Pod is created with liveness probe on http endpoint /redirect?loc=healthz. The http handler on the /redirect will redirect to the /healthz endpoint, which will return a http error after 10 seconds since the Pod is started. This MUST result in liveness check failure. The Pod MUST now be killed and restarted incrementing restart count to 1. */ @@ -242,7 +242,7 @@ var _ = framework.KubeDescribe("Probing container", func() { }) /* - Release : v1.14 + Release: v1.14 Testname: Pod http liveness probe, redirected to a non-local address Description: A Pod is created with liveness probe on http endpoint /redirect with a redirect to http://0.0.0.0/. The http handler on the /redirect should not follow the redirect, but instead treat it as a success and generate an event. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/docker_containers.go b/vendor/k8s.io/kubernetes/test/e2e/common/docker_containers.go index 2df882d5aa08..090039136f29 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/docker_containers.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/docker_containers.go @@ -19,7 +19,7 @@ package common import ( "github.com/onsi/gomega" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/kubernetes/test/e2e/framework" @@ -31,7 +31,7 @@ var _ = framework.KubeDescribe("Docker Containers", func() { f := framework.NewDefaultFramework("containers") /* - Release : v1.9 + Release: v1.9 Testname: Docker containers, without command and arguments Description: Default command and arguments from the docker image entrypoint MUST be used when Pod does not specify the container command */ @@ -50,7 +50,7 @@ var _ = framework.KubeDescribe("Docker Containers", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Docker containers, with arguments Description: Default command and from the docker image entrypoint MUST be used when Pod does not specify the container command but the arguments from Pod spec MUST override when specified. */ @@ -66,7 +66,7 @@ var _ = framework.KubeDescribe("Docker Containers", func() { // Note: when you override the entrypoint, the image's arguments (docker cmd) // are ignored. /* - Release : v1.9 + Release: v1.9 Testname: Docker containers, with command Description: Default command from the docker image entrypoint MUST NOT be used when Pod specifies the container command. Command from Pod spec MUST override the command in the image. */ @@ -80,7 +80,7 @@ var _ = framework.KubeDescribe("Docker Containers", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Docker containers, with command and arguments Description: Default command and arguments from the docker image entrypoint MUST NOT be used when Pod specifies the container command and arguments. Command and arguments from Pod spec MUST override the command and arguments in the image. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/downward_api.go b/vendor/k8s.io/kubernetes/test/e2e/common/downward_api.go index 92edffbb69fd..22043de61776 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/downward_api.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/downward_api.go @@ -19,7 +19,7 @@ package common import ( "fmt" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" @@ -35,7 +35,7 @@ var _ = ginkgo.Describe("[sig-node] Downward API", func() { f := framework.NewDefaultFramework("downward-api") /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI, environment for name, namespace and ip Description: Downward API MUST expose Pod and Container fields as environment variables. Specify Pod Name, namespace and IP as environment variable in the Pod Spec are visible at runtime in the container. */ @@ -81,7 +81,7 @@ var _ = ginkgo.Describe("[sig-node] Downward API", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI, environment for host ip Description: Downward API MUST expose Pod and Container fields as environment variables. Specify host IP as environment variable in the Pod Spec are visible at runtime in the container. */ @@ -157,7 +157,7 @@ var _ = ginkgo.Describe("[sig-node] Downward API", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI, environment for CPU and memory limits and requests Description: Downward API MUST expose CPU request and Memory request set through environment variables at runtime in the container. */ @@ -208,7 +208,7 @@ var _ = ginkgo.Describe("[sig-node] Downward API", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI, environment for default CPU and memory limits and requests Description: Downward API MUST expose CPU request and Memory limits set through environment variables at runtime in the container. */ @@ -258,7 +258,7 @@ var _ = ginkgo.Describe("[sig-node] Downward API", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI, environment for Pod UID Description: Downward API MUST expose Pod UID set through environment variables at runtime in the container. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/downwardapi_volume.go b/vendor/k8s.io/kubernetes/test/e2e/common/downwardapi_volume.go index c831c019f85b..654a4dc9766d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/downwardapi_volume.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/downwardapi_volume.go @@ -21,7 +21,7 @@ import ( "fmt" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" @@ -44,7 +44,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, pod name Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains a item for the Pod name. The container runtime MUST be able to access Pod name from the specified path on the mounted volume. */ @@ -58,7 +58,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, volume mode 0400 Description: A Pod is configured with DownwardAPIVolumeSource with the volumesource mode set to -r-------- and DownwardAPIVolumeFiles contains a item for the Pod name. The container runtime MUST be able to access Pod name from the specified path on the mounted volume. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -74,7 +74,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, file mode 0400 Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains a item for the Pod name with the file mode set to -r--------. The container runtime MUST be able to access Pod name from the specified path on the mounted volume. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -121,7 +121,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, update label Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains list of items for each of the Pod labels. The container runtime MUST be able to access Pod labels from the specified path on the mounted volume. Update the labels by adding a new label to the running Pod. The new label MUST be available from the mounted volume. */ @@ -153,7 +153,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, update annotations Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains list of items for each of the Pod annotations. The container runtime MUST be able to access Pod annotations from the specified path on the mounted volume. Update the annotations by adding a new annotation to the running Pod. The new annotation MUST be available from the mounted volume. */ @@ -187,7 +187,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, CPU limits Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains a item for the CPU limits. The container runtime MUST be able to access CPU limits from the specified path on the mounted volume. */ @@ -201,7 +201,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, memory limits Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains a item for the memory limits. The container runtime MUST be able to access memory limits from the specified path on the mounted volume. */ @@ -215,7 +215,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, CPU request Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains a item for the CPU request. The container runtime MUST be able to access CPU request from the specified path on the mounted volume. */ @@ -229,7 +229,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, memory request Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains a item for the memory request. The container runtime MUST be able to access memory request from the specified path on the mounted volume. */ @@ -243,7 +243,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, CPU limit, default node allocatable Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains a item for the CPU limits. CPU limits is not specified for the container. The container runtime MUST be able to access CPU limits from the specified path on the mounted volume and the value MUST be default node allocatable. */ @@ -255,7 +255,7 @@ var _ = ginkgo.Describe("[sig-storage] Downward API volume", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DownwardAPI volume, memory limit, default node allocatable Description: A Pod is configured with DownwardAPIVolumeSource and DownwardAPIVolumeFiles contains a item for the memory limits. memory limits is not specified for the container. The container runtime MUST be able to access memory limits from the specified path on the mounted volume and the value MUST be default node allocatable. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/empty_dir.go b/vendor/k8s.io/kubernetes/test/e2e/common/empty_dir.go index f98189a5963e..4392ae950594 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/empty_dir.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/empty_dir.go @@ -75,7 +75,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium memory, volume mode default Description: A Pod created with an 'emptyDir' Volume and 'medium' as 'Memory', the volume MUST have mode set as -rwxrwxrwx and mount type set to tmpfs. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or the medium = 'Memory'. @@ -85,7 +85,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium memory, volume mode 0644 Description: A Pod created with an 'emptyDir' Volume and 'medium' as 'Memory', the volume mode set to 0644. The volume MUST have mode -rw-r--r-- and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID, or the medium = 'Memory'. @@ -95,7 +95,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium memory, volume mode 0666 Description: A Pod created with an 'emptyDir' Volume and 'medium' as 'Memory', the volume mode set to 0666. The volume MUST have mode -rw-rw-rw- and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID, or the medium = 'Memory'. @@ -105,7 +105,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium memory, volume mode 0777 Description: A Pod created with an 'emptyDir' Volume and 'medium' as 'Memory', the volume mode set to 0777. The volume MUST have mode set as -rwxrwxrwx and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID, or the medium = 'Memory'. @@ -115,7 +115,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium memory, volume mode 0644, non-root user Description: A Pod created with an 'emptyDir' Volume and 'medium' as 'Memory', the volume mode set to 0644. Volume is mounted into the container where container is run as a non-root user. The volume MUST have mode -rw-r--r-- and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID, or the medium = 'Memory'. @@ -125,7 +125,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium memory, volume mode 0666,, non-root user Description: A Pod created with an 'emptyDir' Volume and 'medium' as 'Memory', the volume mode set to 0666. Volume is mounted into the container where container is run as a non-root user. The volume MUST have mode -rw-rw-rw- and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID, or the medium = 'Memory'. @@ -135,7 +135,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium memory, volume mode 0777, non-root user Description: A Pod created with an 'emptyDir' Volume and 'medium' as 'Memory', the volume mode set to 0777. Volume is mounted into the container where container is run as a non-root user. The volume MUST have mode -rwxrwxrwx and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID, or the medium = 'Memory'. @@ -145,7 +145,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium default, volume mode default Description: A Pod created with an 'emptyDir' Volume, the volume MUST have mode set as -rwxrwxrwx and mount type set to tmpfs. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -155,7 +155,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium default, volume mode 0644 Description: A Pod created with an 'emptyDir' Volume, the volume mode set to 0644. The volume MUST have mode -rw-r--r-- and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID. @@ -165,7 +165,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium default, volume mode 0666 Description: A Pod created with an 'emptyDir' Volume, the volume mode set to 0666. The volume MUST have mode -rw-rw-rw- and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID. @@ -175,7 +175,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium default, volume mode 0777 Description: A Pod created with an 'emptyDir' Volume, the volume mode set to 0777. The volume MUST have mode set as -rwxrwxrwx and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID. @@ -185,7 +185,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium default, volume mode 0644 Description: A Pod created with an 'emptyDir' Volume, the volume mode set to 0644. Volume is mounted into the container where container is run as a non-root user. The volume MUST have mode -rw-r--r-- and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID. @@ -195,7 +195,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium default, volume mode 0666 Description: A Pod created with an 'emptyDir' Volume, the volume mode set to 0666. Volume is mounted into the container where container is run as a non-root user. The volume MUST have mode -rw-rw-rw- and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID. @@ -205,7 +205,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: EmptyDir, medium default, volume mode 0777 Description: A Pod created with an 'emptyDir' Volume, the volume mode set to 0777. Volume is mounted into the container where container is run as a non-root user. The volume MUST have mode -rwxrwxrwx and mount type set to tmpfs and the contents MUST be readable. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID. @@ -215,7 +215,7 @@ var _ = ginkgo.Describe("[sig-storage] EmptyDir volumes", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: EmptyDir, Shared volumes between containers Description: A Pod created with an 'emptyDir' Volume, should share volumes between the containeres in the pod. The two busybox image containers shoud share the volumes mounted to the pod. The main container shoud wait until the sub container drops a file, and main container acess the shared data. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/expansion.go b/vendor/k8s.io/kubernetes/test/e2e/common/expansion.go index 5d09966f3654..2513401792c7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/expansion.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/expansion.go @@ -34,7 +34,7 @@ var _ = framework.KubeDescribe("Variable Expansion", func() { f := framework.NewDefaultFramework("var-expansion") /* - Release : v1.9 + Release: v1.9 Testname: Environment variables, expansion Description: Create a Pod with environment variables. Environment variables defined using previously defined environment variables MUST expand to proper values. */ @@ -63,7 +63,7 @@ var _ = framework.KubeDescribe("Variable Expansion", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Environment variables, command expansion Description: Create a Pod with environment variables and container command using them. Container command using the defined environment variables MUST expand to proper values. */ @@ -82,7 +82,7 @@ var _ = framework.KubeDescribe("Variable Expansion", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Environment variables, command argument expansion Description: Create a Pod with environment variables and container command arguments using them. Container command arguments using the defined environment variables MUST expand to proper values. */ @@ -102,7 +102,7 @@ var _ = framework.KubeDescribe("Variable Expansion", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: VolumeSubpathEnvExpansion, subpath expansion Description: Make sure a container's subpath can be set using an expansion of environment variables. */ @@ -142,7 +142,7 @@ var _ = framework.KubeDescribe("Variable Expansion", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: VolumeSubpathEnvExpansion, subpath with backticks Description: Make sure a container's subpath can not be set using an expansion of environment variables when backticks are supplied. */ @@ -176,7 +176,7 @@ var _ = framework.KubeDescribe("Variable Expansion", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: VolumeSubpathEnvExpansion, subpath with absolute path Description: Make sure a container's subpath can not be set using an expansion of environment variables when absolute path is supplied. */ @@ -210,7 +210,7 @@ var _ = framework.KubeDescribe("Variable Expansion", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: VolumeSubpathEnvExpansion, subpath ready from failed state Description: Verify that a failing subpath expansion can be modified during the lifecycle of a container. */ @@ -275,7 +275,7 @@ var _ = framework.KubeDescribe("Variable Expansion", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: VolumeSubpathEnvExpansion, subpath test writes Description: Verify that a subpath expansion can be used to write files into subpaths. 1. valid subpathexpr starts a container running diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/kubelet.go b/vendor/k8s.io/kubernetes/test/e2e/common/kubelet.go index 1c0502d28023..c6182a01195c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/kubelet.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/kubelet.go @@ -42,7 +42,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { podName := "busybox-scheduling-" + string(uuid.NewUUID()) /* - Release : v1.13 + Release: v1.13 Testname: Kubelet, log output, default Description: By default the stdout and stderr from the process being executed in a pod MUST be sent to the pod's logs. */ @@ -100,7 +100,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { }) /* - Release : v1.13 + Release: v1.13 Testname: Kubelet, failed pod, terminated reason Description: Create a Pod with terminated state. Pod MUST have only one container. Container MUST be in terminated state and MUST have an terminated reason. */ @@ -125,7 +125,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { }) /* - Release : v1.13 + Release: v1.13 Testname: Kubelet, failed pod, delete Description: Create a Pod with terminated state. This terminated pod MUST be able to be deleted. */ @@ -138,7 +138,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { podName := "busybox-host-aliases" + string(uuid.NewUUID()) /* - Release : v1.13 + Release: v1.13 Testname: Kubelet, hostAliases Description: Create a Pod with hostAliases and a container with command to output /etc/hosts entries. Pod's logs MUST have matching entries of specified hostAliases to the output of /etc/hosts entries. Kubernetes mounts the /etc/hosts file into its containers, however, mounting individual files is not supported on Windows Containers. For this reason, this test is marked LinuxOnly. @@ -189,7 +189,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { podName := "busybox-readonly-fs" + string(uuid.NewUUID()) /* - Release : v1.13 + Release: v1.13 Testname: Kubelet, pod with read only root file system Description: Create a Pod with security context set with ReadOnlyRootFileSystem set to true. The Pod then tries to write to the /file on the root, write operation to the root filesystem MUST fail as expected. This test is marked LinuxOnly since Windows does not support creating containers with read-only access. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/kubelet_etc_hosts.go b/vendor/k8s.io/kubernetes/test/e2e/common/kubelet_etc_hosts.go index 868026867ef0..b4ff6ecde90c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/kubelet_etc_hosts.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/kubelet_etc_hosts.go @@ -51,7 +51,7 @@ var _ = framework.KubeDescribe("KubeletManagedEtcHosts", func() { } /* - Release : v1.9 + Release: v1.9 Testname: Kubelet, managed etc hosts Description: Create a Pod with containers with hostNetwork set to false, one of the containers mounts the /etc/hosts file form the host. Create a second Pod with hostNetwork set to true. 1. The Pod with hostNetwork=false MUST have /etc/hosts of containers managed by the Kubelet. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/lease.go b/vendor/k8s.io/kubernetes/test/e2e/common/lease.go index f87ca02e9a6f..04e68fedcfbc 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/lease.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/lease.go @@ -53,7 +53,7 @@ var _ = framework.KubeDescribe("Lease", func() { f := framework.NewDefaultFramework("lease-test") /* - Release : v1.17 + Release: v1.17 Testname: lease API should be available Description: Create Lease object, and get it; create and get MUST be successful and Spec of the read Lease MUST match Spec of original Lease. Update the Lease and get it; update and get MUST diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/lifecycle_hook.go b/vendor/k8s.io/kubernetes/test/e2e/common/lifecycle_hook.go index 3ae5511caba4..0150cb4913da 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/lifecycle_hook.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/lifecycle_hook.go @@ -21,7 +21,7 @@ import ( "strings" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/kubernetes/test/e2e/framework" @@ -92,7 +92,7 @@ var _ = framework.KubeDescribe("Container Lifecycle Hook", func() { } } /* - Release : v1.9 + Release: v1.9 Testname: Pod Lifecycle, post start exec hook Description: When a post start handler is specified in the container lifecycle using a 'Exec' action, then the handler MUST be invoked after the start of the container. A server pod is created that will serve http requests, create a second pod with a container lifecycle specifying a post start that invokes the server pod using ExecAction to validate that the post start is executed. */ @@ -108,7 +108,7 @@ var _ = framework.KubeDescribe("Container Lifecycle Hook", func() { testPodWithHook(podWithHook) }) /* - Release : v1.9 + Release: v1.9 Testname: Pod Lifecycle, prestop exec hook Description: When a pre-stop handler is specified in the container lifecycle using a 'Exec' action, then the handler MUST be invoked before the container is terminated. A server pod is created that will serve http requests, create a second pod with a container lifecycle specifying a pre-stop that invokes the server pod using ExecAction to validate that the pre-stop is executed. */ @@ -124,7 +124,7 @@ var _ = framework.KubeDescribe("Container Lifecycle Hook", func() { testPodWithHook(podWithHook) }) /* - Release : v1.9 + Release: v1.9 Testname: Pod Lifecycle, post start http hook Description: When a post start handler is specified in the container lifecycle using a HttpGet action, then the handler MUST be invoked after the start of the container. A server pod is created that will serve http requests, create a second pod with a container lifecycle specifying a post start that invokes the server pod to validate that the post start is executed. */ @@ -142,7 +142,7 @@ var _ = framework.KubeDescribe("Container Lifecycle Hook", func() { testPodWithHook(podWithHook) }) /* - Release : v1.9 + Release: v1.9 Testname: Pod Lifecycle, prestop http hook Description: When a pre-stop handler is specified in the container lifecycle using a 'HttpGet' action, then the handler MUST be invoked before the container is terminated. A server pod is created that will serve http requests, create a second pod with a container lifecycle specifying a pre-stop that invokes the server pod to validate that the pre-stop is executed. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/networking.go b/vendor/k8s.io/kubernetes/test/e2e/common/networking.go index 868977f54045..97010b2d734f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/networking.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/networking.go @@ -32,7 +32,7 @@ var _ = ginkgo.Describe("[sig-network] Networking", func() { // expect exactly one unique hostname. Each of these endpoints reports // its own hostname. /* - Release : v1.9, v1.18 + Release: v1.9, v1.18 Testname: Networking, intra pod http Description: Create a hostexec pod that is capable of curl to netcat commands. Create a test Pod that will act as a webserver front end exposing ports 8080 for tcp and 8081 for udp. The netserver service proxies are created on specified number of nodes. The kubectl exec on the webserver container MUST reach a http port on the each of service proxy endpoints in the cluster and the request MUST be successful. Container will execute curl command to reach the service port within specified max retry limit and MUST result in reporting unique hostnames. @@ -45,7 +45,7 @@ var _ = ginkgo.Describe("[sig-network] Networking", func() { }) /* - Release : v1.9, v1.18 + Release: v1.9, v1.18 Testname: Networking, intra pod udp Description: Create a hostexec pod that is capable of curl to netcat commands. Create a test Pod that will act as a webserver front end exposing ports 8080 for tcp and 8081 for udp. The netserver service proxies are created on specified number of nodes. The kubectl exec on the webserver container MUST reach a udp port on the each of service proxy endpoints in the cluster and the request MUST be successful. Container will execute curl command to reach the service port within specified max retry limit and MUST result in reporting unique hostnames. @@ -58,7 +58,7 @@ var _ = ginkgo.Describe("[sig-network] Networking", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Networking, intra pod http, from node Description: Create a hostexec pod that is capable of curl to netcat commands. Create a test Pod that will act as a webserver front end exposing ports 8080 for tcp and 8081 for udp. The netserver service proxies are created on specified number of nodes. The kubectl exec on the webserver container MUST reach a http port on the each of service proxy endpoints in the cluster using a http post(protocol=tcp) and the request MUST be successful. Container will execute curl command to reach the service port within specified max retry limit and MUST result in reporting unique hostnames. @@ -72,7 +72,7 @@ var _ = ginkgo.Describe("[sig-network] Networking", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Networking, intra pod http, from node Description: Create a hostexec pod that is capable of curl to netcat commands. Create a test Pod that will act as a webserver front end exposing ports 8080 for tcp and 8081 for udp. The netserver service proxies are created on specified number of nodes. The kubectl exec on the webserver container MUST reach a http port on the each of service proxy endpoints in the cluster using a http post(protocol=udp) and the request MUST be successful. Container will execute curl command to reach the service port within specified max retry limit and MUST result in reporting unique hostnames. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/pods.go b/vendor/k8s.io/kubernetes/test/e2e/common/pods.go index 279598b7464f..07b4ee36aefc 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/pods.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/pods.go @@ -183,7 +183,7 @@ var _ = framework.KubeDescribe("Pods", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pods, assigned hostip Description: Create a Pod. Pod status MUST return successfully and contains a valid IP address. */ @@ -205,7 +205,7 @@ var _ = framework.KubeDescribe("Pods", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pods, lifecycle Description: A Pod is created with a unique label. Pod MUST be accessible when queried using the label selector upon creation. Add a watch, check if the Pod is running. Pod then deleted, The pod deletion timestamp is observed. The watch MUST return the pod deleted event. Query with the original selector for the Pod MUST return empty list. */ @@ -336,7 +336,7 @@ var _ = framework.KubeDescribe("Pods", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pods, update Description: Create a Pod with a unique label. Query for the Pod with the label as selector MUST be successful. Update the pod to change the value of the Label. Query for the Pod with the new value for the label MUST be successful. Behaviors: @@ -393,7 +393,7 @@ var _ = framework.KubeDescribe("Pods", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pods, ActiveDeadlineSeconds Description: Create a Pod with a unique label. Query for the Pod with the label as selector MUST be successful. The Pod is updated with ActiveDeadlineSeconds set on the Pod spec. Pod MUST terminate of the specified time elapses. */ @@ -439,7 +439,7 @@ var _ = framework.KubeDescribe("Pods", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pods, service environment variables Description: Create a server Pod listening on port 9376. A Service called fooservice is created for the server Pod listening on port 8765 targeting port 8080. If a new Pod is created in the cluster then the Pod MUST have the fooservice environment variables available from this new Pod. The new create Pod MUST have environment variables such as FOOSERVICE_SERVICE_HOST, FOOSERVICE_SERVICE_PORT, FOOSERVICE_PORT, FOOSERVICE_PORT_8765_TCP_PORT, FOOSERVICE_PORT_8765_TCP_PROTO, FOOSERVICE_PORT_8765_TCP and FOOSERVICE_PORT_8765_TCP_ADDR that are populated with proper values. */ @@ -530,7 +530,7 @@ var _ = framework.KubeDescribe("Pods", func() { }) /* - Release : v1.13 + Release: v1.13 Testname: Pods, remote command execution over websocket Description: A Pod is created. Websocket is created to retrieve exec command output from this pod. Message retrieved form Websocket MUST match with expected exec command output. @@ -612,7 +612,7 @@ var _ = framework.KubeDescribe("Pods", func() { }) /* - Release : v1.13 + Release: v1.13 Testname: Pods, logs from websockets Description: A Pod is created. Websocket is created to retrieve log of a container from this pod. Message retrieved form Websocket MUST match with container's output. @@ -832,9 +832,17 @@ var _ = framework.KubeDescribe("Pods", func() { }) - ginkgo.It("should delete a collection of pods", func() { + /* + Release: v1.19 + Testname: Pods, delete a collection + Description: A set of pods is created with a label selector which MUST be found when listed. + The set of pods is deleted and MUST NOT show up when listed by its label selector. + */ + framework.ConformanceIt("should delete a collection of pods", func() { podTestNames := []string{"test-pod-1", "test-pod-2", "test-pod-3"} + zero := int64(0) + ginkgo.By("Create set of pods") // create a set of pods in test namespace for _, podTestName := range podTestNames { @@ -845,6 +853,7 @@ var _ = framework.KubeDescribe("Pods", func() { "type": "Testing"}, }, Spec: v1.PodSpec{ + TerminationGracePeriodSeconds: &zero, Containers: []v1.Container{{ Image: imageutils.GetE2EImage(imageutils.Agnhost), Name: "token-test", @@ -861,7 +870,7 @@ var _ = framework.KubeDescribe("Pods", func() { framework.ExpectNoError(err, "3 pods not found") // delete Collection of pods with a label in the current namespace - err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{ + err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).DeleteCollection(context.TODO(), metav1.DeleteOptions{GracePeriodSeconds: &zero}, metav1.ListOptions{ LabelSelector: "type=Testing"}) framework.ExpectNoError(err, "failed to delete collection of pods") diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/podtemplates.go b/vendor/k8s.io/kubernetes/test/e2e/common/podtemplates.go index 4adefe1c184e..dbf1354e9099 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/podtemplates.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/podtemplates.go @@ -20,6 +20,8 @@ import ( "context" "encoding/json" + "time" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -27,7 +29,6 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/kubernetes/test/e2e/framework" imageutils "k8s.io/kubernetes/test/utils/image" - "time" "github.com/onsi/ginkgo" ) @@ -40,7 +41,7 @@ const ( var _ = ginkgo.Describe("[sig-node] PodTemplates", func() { f := framework.NewDefaultFramework("podtemplate") /* - Release : v1.19 + Release: v1.19 Testname: PodTemplate lifecycle Description: Attempt to create a PodTemplate. Patch the created PodTemplate. Fetching the PodTemplate MUST reflect changes. By fetching all the PodTemplates via a Label selector it MUST find the PodTemplate by it's static label and updated value. The PodTemplate must be deleted. @@ -109,7 +110,7 @@ var _ = ginkgo.Describe("[sig-node] PodTemplates", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: PodTemplate, delete a collection Description: A set of Pod Templates is created with a label selector which MUST be found when listed. The set of Pod Templates is deleted and MUST NOT show up when listed by its label selector. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/projected_combined.go b/vendor/k8s.io/kubernetes/test/e2e/common/projected_combined.go index 8cf96eada75c..52bebcc16f2f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/projected_combined.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/projected_combined.go @@ -20,7 +20,7 @@ import ( "context" "fmt" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/kubernetes/test/e2e/framework" @@ -34,7 +34,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected combined", func() { // Test multiple projections /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, multiple projections Description: A Pod is created with a projected volume source for secrets, configMap and downwardAPI with pod name, cpu and memory limits and cpu and memory requests. Pod MUST be able to read the secrets, configMap values and the cpu and memory limits as well as cpu and memory requests from the mounted DownwardAPIVolumeFiles. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/projected_configmap.go b/vendor/k8s.io/kubernetes/test/e2e/common/projected_configmap.go index 970db1da99f5..e218e9b21d4a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/projected_configmap.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/projected_configmap.go @@ -21,7 +21,7 @@ import ( "fmt" "path" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/kubernetes/test/e2e/framework" @@ -37,7 +37,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { f := framework.NewDefaultFramework("projected") /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, volume mode default Description: A Pod is created with projected volume source 'ConfigMap' to store a configMap with default permission mode. Pod MUST be able to read the content of the ConfigMap successfully and the mode on the volume MUST be -rw-r--r--. */ @@ -46,7 +46,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, volume mode 0400 Description: A Pod is created with projected volume source 'ConfigMap' to store a configMap with permission mode set to 0400. Pod MUST be able to read the content of the ConfigMap successfully and the mode on the volume MUST be -r--------. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -64,7 +64,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, non-root user Description: A Pod is created with projected volume source 'ConfigMap' to store a configMap as non-root user with uid 1000. Pod MUST be able to read the content of the ConfigMap successfully and the mode on the volume MUST be -rw-r--r--. */ @@ -79,7 +79,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, mapped Description: A Pod is created with projected volume source 'ConfigMap' to store a configMap with default permission mode. The ConfigMap is also mapped to a custom path. Pod MUST be able to read the content of the ConfigMap from the custom location successfully and the mode on the volume MUST be -rw-r--r--. */ @@ -88,7 +88,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, mapped, volume mode 0400 Description: A Pod is created with projected volume source 'ConfigMap' to store a configMap with permission mode set to 0400. The ConfigMap is also mapped to a custom path. Pod MUST be able to read the content of the ConfigMap from the custom location successfully and the mode on the volume MUST be -r--r--r--. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -99,7 +99,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, mapped, non-root user Description: A Pod is created with projected volume source 'ConfigMap' to store a configMap as non-root user with uid 1000. The ConfigMap is also mapped to a custom path. Pod MUST be able to read the content of the ConfigMap from the custom location successfully and the mode on the volume MUST be -r--r--r--. */ @@ -114,7 +114,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, update Description: A Pod is created with projected volume source 'ConfigMap' to store a configMap and performs a create and update to new value. Pod MUST be able to create the configMap with value-1. Pod MUST be able to update the value in the confgiMap to value-2. */ @@ -202,7 +202,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, create, update and delete Description: Create a Pod with three containers with ConfigMaps namely a create, update and delete container. Create Container when started MUST not have configMap, update and delete containers MUST be created with a ConfigMap value as 'value-1'. Create a configMap in the create container, the Pod MUST be able to read the configMap from the create container. Update the configMap in the update container, Pod MUST be able to read the updated configMap value. Delete the configMap in the delete container. Pod MUST fail to read the configMap from the delete container. */ @@ -403,7 +403,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected configMap", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, ConfigMap, multiple volume paths Description: A Pod is created with a projected volume source 'ConfigMap' to store a configMap. The configMap is mapped to two different volume mounts. Pod MUST be able to read the content of the configMap successfully from the two volume mounts. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/projected_downwardapi.go b/vendor/k8s.io/kubernetes/test/e2e/common/projected_downwardapi.go index 77b5d871d035..4ad2f16f80e3 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/projected_downwardapi.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/projected_downwardapi.go @@ -21,7 +21,7 @@ import ( "fmt" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/kubernetes/test/e2e/framework" @@ -44,7 +44,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, pod name Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. Pod MUST be able to read the pod name from the mounted DownwardAPIVolumeFiles. */ @@ -58,7 +58,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, volume mode 0400 Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. The default mode for the volume mount is set to 0400. Pod MUST be able to read the pod name from the mounted DownwardAPIVolumeFiles and the volume mode must be -r--------. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -74,7 +74,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, volume mode 0400 Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. The default mode for the volume mount is set to 0400. Pod MUST be able to read the pod name from the mounted DownwardAPIVolumeFiles and the volume mode must be -r--------. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -121,7 +121,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, update labels Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests and label items. Pod MUST be able to read the labels from the mounted DownwardAPIVolumeFiles. Labels are then updated. Pod MUST be able to read the updated values for the Labels. */ @@ -153,7 +153,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, update annotation Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests and annotation items. Pod MUST be able to read the annotations from the mounted DownwardAPIVolumeFiles. Annotations are then updated. Pod MUST be able to read the updated values for the Annotations. */ @@ -187,7 +187,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, CPU limits Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. Pod MUST be able to read the cpu limits from the mounted DownwardAPIVolumeFiles. */ @@ -201,7 +201,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, memory limits Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. Pod MUST be able to read the memory limits from the mounted DownwardAPIVolumeFiles. */ @@ -215,7 +215,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, CPU request Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. Pod MUST be able to read the cpu request from the mounted DownwardAPIVolumeFiles. */ @@ -229,7 +229,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, memory request Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. Pod MUST be able to read the memory request from the mounted DownwardAPIVolumeFiles. */ @@ -243,7 +243,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, CPU limit, node allocatable Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. The CPU and memory resources for requests and limits are NOT specified for the container. Pod MUST be able to read the default cpu limits from the mounted DownwardAPIVolumeFiles. */ @@ -255,7 +255,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected downwardAPI", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, DownwardAPI, memory limit, node allocatable Description: A Pod is created with a projected volume source for downwardAPI with pod name, cpu and memory limits and cpu and memory requests. The CPU and memory resources for requests and limits are NOT specified for the container. Pod MUST be able to read the default memory limits from the mounted DownwardAPIVolumeFiles. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/projected_secret.go b/vendor/k8s.io/kubernetes/test/e2e/common/projected_secret.go index 2eae78062e8e..25f35b693704 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/projected_secret.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/projected_secret.go @@ -21,7 +21,7 @@ import ( "fmt" "path" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/kubernetes/test/e2e/framework" @@ -36,7 +36,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected secret", func() { f := framework.NewDefaultFramework("projected") /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, Secrets, volume mode default Description: A Pod is created with a projected volume source 'secret' to store a secret with a specified key with default permission mode. Pod MUST be able to read the content of the key successfully and the mode MUST be -rw-r--r-- by default. */ @@ -45,7 +45,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected secret", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, Secrets, volume mode 0400 Description: A Pod is created with a projected volume source 'secret' to store a secret with a specified key with permission mode set to 0x400 on the Pod. Pod MUST be able to read the content of the key successfully and the mode MUST be -r--------. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -56,7 +56,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected secret", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Project Volume, Secrets, non-root, custom fsGroup Description: A Pod is created with a projected volume source 'secret' to store a secret with a specified key. The volume has permission mode set to 0440, fsgroup set to 1001 and user set to non-root uid of 1000. Pod MUST be able to read the content of the key successfully and the mode MUST be -r--r-----. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID. @@ -68,7 +68,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected secret", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, Secrets, mapped Description: A Pod is created with a projected volume source 'secret' to store a secret with a specified key with default permission mode. The secret is also mapped to a custom path. Pod MUST be able to read the content of the key successfully and the mode MUST be -r--------on the mapped volume. */ @@ -77,7 +77,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected secret", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, Secrets, mapped, volume mode 0400 Description: A Pod is created with a projected volume source 'secret' to store a secret with a specified key with permission mode set to 0400. The secret is also mapped to a specific name. Pod MUST be able to read the content of the key successfully and the mode MUST be -r-------- on the mapped volume. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -109,7 +109,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected secret", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, Secrets, mapped, multiple paths Description: A Pod is created with a projected volume source 'secret' to store a secret with a specified key. The secret is mapped to two different volume mounts. Pod MUST be able to read the content of the key successfully from the two volume mounts and the mode MUST be -r-------- on the mapped volumes. */ @@ -205,7 +205,7 @@ var _ = ginkgo.Describe("[sig-storage] Projected secret", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Projected Volume, Secrets, create, update delete Description: Create a Pod with three containers with secrets namely a create, update and delete container. Create Container when started MUST no have a secret, update and delete containers MUST be created with a secret value. Create a secret in the create container, the Pod MUST be able to read the secret from the create container. Update the secret in the update container, Pod MUST be able to read the updated secret value. Delete the secret in the delete container. Pod MUST fail to read the secret from the delete container. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/runtime.go b/vendor/k8s.io/kubernetes/test/e2e/common/runtime.go index ee7954d28d49..a96b9e2ff183 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/runtime.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/runtime.go @@ -42,7 +42,7 @@ var _ = framework.KubeDescribe("Container Runtime", func() { ginkgo.Context("when starting a container that exits", func() { /* - Release : v1.13 + Release: v1.13 Testname: Container Runtime, Restart Policy, Pod Phases Description: If the restart policy is set to 'Always', Pod MUST be restarted when terminated, If restart policy is 'OnFailure', Pod MUST be started only if it is terminated with non-zero exit code. If the restart policy is 'Never', Pod MUST never be restarted. All these three test cases MUST verify the restart counts accordingly. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/runtimeclass.go b/vendor/k8s.io/kubernetes/test/e2e/common/runtimeclass.go index 6b7b5b4776f8..9a0970a68ac5 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/runtimeclass.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/runtimeclass.go @@ -97,16 +97,9 @@ func createRuntimeClass(f *framework.Framework, name, handler string) string { } func expectPodRejection(f *framework.Framework, pod *v1.Pod) { - // The Node E2E doesn't run the RuntimeClass admission controller, so we expect the rejection to - // happen by the Kubelet. - if framework.TestContext.NodeE2E { - pod = f.PodClient().Create(pod) - expectSandboxFailureEvent(f, pod, fmt.Sprintf("\"%s\" not found", *pod.Spec.RuntimeClassName)) - } else { - _, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), pod, metav1.CreateOptions{}) - framework.ExpectError(err, "should be forbidden") - framework.ExpectEqual(apierrors.IsForbidden(err), true, "should be forbidden error") - } + _, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), pod, metav1.CreateOptions{}) + framework.ExpectError(err, "should be forbidden") + framework.ExpectEqual(apierrors.IsForbidden(err), true, "should be forbidden error") } // expectPodSuccess waits for the given pod to terminate successfully. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/secrets.go b/vendor/k8s.io/kubernetes/test/e2e/common/secrets.go index 538dd7fd7c7b..cfc887542a3b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/secrets.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/secrets.go @@ -21,13 +21,14 @@ import ( "encoding/json" "fmt" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/kubernetes/test/e2e/framework" imageutils "k8s.io/kubernetes/test/utils/image" "encoding/base64" + "github.com/onsi/ginkgo" "k8s.io/apimachinery/pkg/types" ) @@ -36,7 +37,7 @@ var _ = ginkgo.Describe("[sig-api-machinery] Secrets", func() { f := framework.NewDefaultFramework("secrets") /* - Release : v1.9 + Release: v1.9 Testname: Secrets, pod environment field Description: Create a secret. Create a Pod with Container that declares a environment variable which references the secret created to extract a key value from the secret. Pod MUST have the environment variable that contains proper value for the key to the secret. */ @@ -85,7 +86,7 @@ var _ = ginkgo.Describe("[sig-api-machinery] Secrets", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Secrets, pod environment from source Description: Create a secret. Create a Pod with Container that declares a environment variable using 'EnvFrom' which references the secret created to extract a key value from the secret. Pod MUST have the environment variable that contains proper value for the key to the secret. */ @@ -130,7 +131,7 @@ var _ = ginkgo.Describe("[sig-api-machinery] Secrets", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: Secrets, with empty-key Description: Attempt to create a Secret with an empty key. The creation MUST fail. */ @@ -140,7 +141,7 @@ var _ = ginkgo.Describe("[sig-api-machinery] Secrets", func() { }) /* - Release : v1.18 + Release: v1.18 Testname: Secret patching Description: A Secret is created. Listing all Secrets MUST return an empty list. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/secrets_volume.go b/vendor/k8s.io/kubernetes/test/e2e/common/secrets_volume.go index d6ebc3bce84c..b6b9e32c16cc 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/secrets_volume.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/secrets_volume.go @@ -21,7 +21,7 @@ import ( "fmt" "path" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" @@ -37,7 +37,7 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() { f := framework.NewDefaultFramework("secrets") /* - Release : v1.9 + Release: v1.9 Testname: Secrets Volume, default Description: Create a secret. Create a Pod with secret volume source configured into the container. Pod MUST be able to read the secret from the mounted volume from the container runtime and the file mode of the secret MUST be -rw-r--r-- by default. */ @@ -46,7 +46,7 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Secrets Volume, volume mode 0400 Description: Create a secret. Create a Pod with secret volume source configured into the container with file mode set to 0x400. Pod MUST be able to read the secret from the mounted volume from the container runtime and the file mode of the secret MUST be -r-------- by default. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -57,7 +57,7 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Secrets Volume, volume mode 0440, fsGroup 1001 and uid 1000 Description: Create a secret. Create a Pod with secret volume source configured into the container with file mode set to 0x440 as a non-root user with uid 1000 and fsGroup id 1001. Pod MUST be able to read the secret from the mounted volume from the container runtime and the file mode of the secret MUST be -r--r-----by default. This test is marked LinuxOnly since Windows does not support setting specific file permissions, or running as UID / GID. @@ -69,7 +69,7 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Secrets Volume, mapping Description: Create a secret. Create a Pod with secret volume source configured into the container with a custom path. Pod MUST be able to read the secret from the mounted volume from the specified custom path. The file mode of the secret MUST be -rw-r--r-- by default. */ @@ -78,7 +78,7 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Secrets Volume, mapping, volume mode 0400 Description: Create a secret. Create a Pod with secret volume source configured into the container with a custom path and file mode set to 0x400. Pod MUST be able to read the secret from the mounted volume from the specified custom path. The file mode of the secret MUST be -r--r--r--. This test is marked LinuxOnly since Windows does not support setting specific file permissions. @@ -89,7 +89,7 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() { }) /* - Release : v1.12 + Release: v1.12 Testname: Secrets Volume, volume mode default, secret with same name in different namespace Description: Create a secret with same name in two namespaces. Create a Pod with secret volume source configured into the container. Pod MUST be able to read the secrets from the mounted volume from the container runtime and only secrets which are associated with namespace where pod is created. The file mode of the secret MUST be -rw-r--r-- by default. */ @@ -115,7 +115,7 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Secrets Volume, mapping multiple volume paths Description: Create a secret. Create a Pod with two secret volume sources configured into the container in to two different custom paths. Pod MUST be able to read the secret from the both the mounted volumes from the two specified custom paths. */ @@ -195,7 +195,7 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Secrets Volume, create, update and delete Description: Create a Pod with three containers with secrets volume sources namely a create, update and delete container. Create Container when started MUST not have secret, update and delete containers MUST be created with a secret value. Create a secret in the create container, the Pod MUST be able to read the secret from the create container. Update the secret in the update container, Pod MUST be able to read the updated secret value. Delete the secret in the delete container. Pod MUST fail to read the secret from the delete container. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/security_context.go b/vendor/k8s.io/kubernetes/test/e2e/common/security_context.go index 2ccfcbc5f947..939464f78fa1 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/security_context.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/security_context.go @@ -75,7 +75,7 @@ var _ = framework.KubeDescribe("Security Context", func() { } /* - Release : v1.15 + Release: v1.15 Testname: Security Context, runAsUser=65534 Description: Container is created with runAsUser option by passing uid 65534 to run as unpriviledged user. Pod MUST be in Succeeded phase. [LinuxOnly]: This test is marked as LinuxOnly since Windows does not support running as UID / GID. @@ -85,7 +85,7 @@ var _ = framework.KubeDescribe("Security Context", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: Security Context, runAsUser=0 Description: Container is created with runAsUser option by passing uid 0 to run as root priviledged user. Pod MUST be in Succeeded phase. This e2e can not be promoted to Conformance because a Conformant platform may not allow to run containers with 'uid 0' or running privileged operations. @@ -202,7 +202,7 @@ var _ = framework.KubeDescribe("Security Context", func() { } /* - Release : v1.15 + Release: v1.15 Testname: Security Context, readOnlyRootFilesystem=true. Description: Container is configured to run with readOnlyRootFilesystem to true which will force containers to run with a read only root file system. Write operation MUST NOT be allowed and Pod MUST be in Failed state. @@ -214,7 +214,7 @@ var _ = framework.KubeDescribe("Security Context", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: Security Context, readOnlyRootFilesystem=false. Description: Container is configured to run with readOnlyRootFilesystem to false. Write operation MUST be allowed and Pod MUST be in Succeeded state. @@ -256,7 +256,7 @@ var _ = framework.KubeDescribe("Security Context", func() { return podName } /* - Release : v1.15 + Release: v1.15 Testname: Security Context, privileged=false. Description: Create a container to run in unprivileged mode by setting pod's SecurityContext Privileged option as false. Pod MUST be in Succeeded phase. [LinuxOnly]: This test is marked as LinuxOnly since it runs a Linux-specific command. @@ -319,7 +319,7 @@ var _ = framework.KubeDescribe("Security Context", func() { } /* - Release : v1.15 + Release: v1.15 Testname: Security Context, allowPrivilegeEscalation unset, uid != 0. Description: Configuring the allowPrivilegeEscalation unset, allows the privilege escalation operation. A container is configured with allowPrivilegeEscalation not specified (nil) and a given uid which is not 0. @@ -335,7 +335,7 @@ var _ = framework.KubeDescribe("Security Context", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: Security Context, allowPrivilegeEscalation=false. Description: Configuring the allowPrivilegeEscalation to false, does not allow the privilege escalation operation. A container is configured with allowPrivilegeEscalation=false and a given uid (1000) which is not 0. @@ -351,7 +351,7 @@ var _ = framework.KubeDescribe("Security Context", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: Security Context, allowPrivilegeEscalation=true. Description: Configuring the allowPrivilegeEscalation to true, allows the privilege escalation operation. A container is configured with allowPrivilegeEscalation=true and a given uid (1000) which is not 0. diff --git a/vendor/k8s.io/kubernetes/test/e2e/examples.go b/vendor/k8s.io/kubernetes/test/e2e/examples.go index 4e030bdb2404..599725728d58 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/examples.go +++ b/vendor/k8s.io/kubernetes/test/e2e/examples.go @@ -68,10 +68,9 @@ var _ = framework.KubeDescribe("[Feature:Example]", func() { test := "test/fixtures/doc-yaml/user-guide/liveness" execYaml := readFile(test, "exec-liveness.yaml.in") httpYaml := readFile(test, "http-liveness.yaml.in") - nsFlag := fmt.Sprintf("--namespace=%v", ns) - framework.RunKubectlOrDieInput(ns, execYaml, "create", "-f", "-", nsFlag) - framework.RunKubectlOrDieInput(ns, httpYaml, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, execYaml, "create", "-f", "-") + framework.RunKubectlOrDieInput(ns, httpYaml, "create", "-f", "-") // Since both containers start rapidly, we can easily run this test in parallel. var wg sync.WaitGroup @@ -117,12 +116,11 @@ var _ = framework.KubeDescribe("[Feature:Example]", func() { secretYaml := readFile(test, "secret.yaml") podYaml := readFile(test, "secret-pod.yaml.in") - nsFlag := fmt.Sprintf("--namespace=%v", ns) podName := "secret-test-pod" ginkgo.By("creating secret and pod") - framework.RunKubectlOrDieInput(ns, secretYaml, "create", "-f", "-", nsFlag) - framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, secretYaml, "create", "-f", "-") + framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-") err := e2epod.WaitForPodNoLongerRunningInNamespace(c, podName, ns) framework.ExpectNoError(err) @@ -136,11 +134,10 @@ var _ = framework.KubeDescribe("[Feature:Example]", func() { ginkgo.It("should create a pod that prints his name and namespace", func() { test := "test/fixtures/doc-yaml/user-guide/downward-api" podYaml := readFile(test, "dapi-pod.yaml.in") - nsFlag := fmt.Sprintf("--namespace=%v", ns) podName := "dapi-test-pod" ginkgo.By("creating the pod") - framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-") err := e2epod.WaitForPodNoLongerRunningInNamespace(c, podName, ns) framework.ExpectNoError(err) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/BUILD b/vendor/k8s.io/kubernetes/test/e2e/framework/BUILD index 3f7567b62dc6..43f11641e2c7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/BUILD @@ -105,6 +105,7 @@ filegroup( "//test/e2e/framework/config:all-srcs", "//test/e2e/framework/deployment:all-srcs", "//test/e2e/framework/endpoints:all-srcs", + "//test/e2e/framework/endpointslice:all-srcs", "//test/e2e/framework/events:all-srcs", "//test/e2e/framework/ginkgowrapper:all-srcs", "//test/e2e/framework/gpu:all-srcs", diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/endpoints/ports.go b/vendor/k8s.io/kubernetes/test/e2e/framework/endpoints/ports.go index 56b9e82c43dd..efd960d93f4b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/endpoints/ports.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/endpoints/ports.go @@ -14,12 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -/* -This soak tests places a specified number of pods on each node and then -repeatedly sends queries to a service running on these pods via -a serivce -*/ - package endpoints import ( diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/endpointslice/BUILD b/vendor/k8s.io/kubernetes/test/e2e/framework/endpointslice/BUILD new file mode 100644 index 000000000000..95592783c770 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/endpointslice/BUILD @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["ports.go"], + importpath = "k8s.io/kubernetes/test/e2e/framework/endpointslice", + visibility = ["//visibility:public"], + deps = [ + "//staging/src/k8s.io/api/discovery/v1beta1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/endpointslice/ports.go b/vendor/k8s.io/kubernetes/test/e2e/framework/endpointslice/ports.go new file mode 100644 index 000000000000..f8aa01d154f7 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/endpointslice/ports.go @@ -0,0 +1,46 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package endpointslice + +import ( + discoveryv1beta1 "k8s.io/api/discovery/v1beta1" + "k8s.io/apimachinery/pkg/types" +) + +// PortsByPodUID is a map that maps pod UID to container ports. +type PortsByPodUID map[types.UID][]int + +// GetContainerPortsByPodUID returns a PortsByPodUID map on the given endpoints. +func GetContainerPortsByPodUID(eps []discoveryv1beta1.EndpointSlice) PortsByPodUID { + m := PortsByPodUID{} + + for _, es := range eps { + for _, port := range es.Ports { + if port.Port == nil { + continue + } + for _, ep := range es.Endpoints { + containerPort := *port.Port + if _, ok := m[ep.TargetRef.UID]; !ok { + m[ep.TargetRef.UID] = make([]int, 0) + } + m[ep.TargetRef.UID] = append(m[ep.TargetRef.UID], int(containerPort)) + } + } + } + return m +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/ingress/ingress_utils.go b/vendor/k8s.io/kubernetes/test/e2e/framework/ingress/ingress_utils.go index ebe8d096826c..8328e2a29959 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/ingress/ingress_utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/ingress/ingress_utils.go @@ -460,10 +460,10 @@ func (j *TestJig) CreateIngress(manifestPath, ns string, ingAnnotations map[stri } j.Logger.Infof("creating replication controller") - framework.RunKubectlOrDieInput(ns, read("rc.yaml"), "create", "-f", "-", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDieInput(ns, read("rc.yaml"), "create", "-f", "-") j.Logger.Infof("creating service") - framework.RunKubectlOrDieInput(ns, read("svc.yaml"), "create", "-f", "-", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDieInput(ns, read("svc.yaml"), "create", "-f", "-") if len(svcAnnotations) > 0 { svcList, err := j.Client.CoreV1().Services(ns).List(context.TODO(), metav1.ListOptions{}) framework.ExpectNoError(err) @@ -476,7 +476,7 @@ func (j *TestJig) CreateIngress(manifestPath, ns string, ingAnnotations map[stri if exists("secret.yaml") { j.Logger.Infof("creating secret") - framework.RunKubectlOrDieInput(ns, read("secret.yaml"), "create", "-f", "-", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDieInput(ns, read("secret.yaml"), "create", "-f", "-") } j.Logger.Infof("Parsing ingress from %v", filepath.Join(manifestPath, "ing.yaml")) @@ -569,7 +569,7 @@ func (j *TestJig) runUpdate(ing *networkingv1beta1.Ingress) (*networkingv1beta1. func DescribeIng(ns string) { framework.Logf("\nOutput of kubectl describe ing:\n") desc, _ := framework.RunKubectl( - ns, "describe", "ing", fmt.Sprintf("--namespace=%v", ns)) + ns, "describe", "ing") framework.Logf(desc) } @@ -1034,7 +1034,7 @@ func (cont *NginxIngressController) Init() { } framework.Logf("initializing nginx ingress controller") - framework.RunKubectlOrDieInput(cont.Ns, read("rc.yaml"), "create", "-f", "-", fmt.Sprintf("--namespace=%v", cont.Ns)) + framework.RunKubectlOrDieInput(cont.Ns, read("rc.yaml"), "create", "-f", "-") rc, err := cont.Client.CoreV1().ReplicationControllers(cont.Ns).Get(context.TODO(), "nginx-ingress-controller", metav1.GetOptions{}) framework.ExpectNoError(err) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go index 0449fc640497..d6765d23b473 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go @@ -86,6 +86,9 @@ func (tk *TestKubeconfig) KubectlCmd(args ...string) *exec.Cmd { fmt.Sprintf("--client-key=%s", filepath.Join(tk.CertDir, "kubecfg.key"))) } } + if tk.Namespace != "" { + defaultArgs = append(defaultArgs, fmt.Sprintf("--namespace=%s", tk.Namespace)) + } kubectlArgs := append(defaultArgs, args...) //We allow users to specify path to kubectl, so you can test either "kubectl" or "cluster/kubectl.sh" diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/network/utils.go b/vendor/k8s.io/kubernetes/test/e2e/framework/network/utils.go index 63006592d828..2a96a28f4e21 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/network/utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/network/utils.go @@ -160,6 +160,12 @@ type NetworkingTestConfig struct { Namespace string } +// NetexecDialResponse represents the response returned by the `netexec` subcommand of `agnhost` +type NetexecDialResponse struct { + Responses []string `json:"responses"` + Errors []string `json:"errors"` +} + // DialFromEndpointContainer executes a curl via kubectl exec in an endpoint container. func (config *NetworkingTestConfig) DialFromEndpointContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) { config.DialFromContainer(protocol, echoHostname, config.EndpointPods[0].Status.PodIP, targetIP, EndpointHTTPPort, targetPort, maxTries, minTries, expectedEps) @@ -212,6 +218,18 @@ func (config *NetworkingTestConfig) EndpointHostnames() sets.String { return expectedEps } +func makeCURLDialCommand(ipPort, dialCmd, protocol, targetIP string, targetPort int) string { + // The current versions of curl included in CentOS and RHEL distros + // misinterpret square brackets around IPv6 as globbing, so use the -g + // argument to disable globbing to handle the IPv6 case. + return fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=%s&protocol=%s&host=%s&port=%d&tries=1'", + ipPort, + dialCmd, + protocol, + targetIP, + targetPort) +} + // DialFromContainer executes a curl via kubectl exec in a test container, // which might then translate to a tcp or udp request based on the protocol // argument in the url. @@ -232,38 +250,23 @@ func (config *NetworkingTestConfig) EndpointHostnames() sets.String { // pod and confirm it doesn't show up as an endpoint. func (config *NetworkingTestConfig) DialFromContainer(protocol, dialCommand, containerIP, targetIP string, containerHTTPPort, targetPort, maxTries, minTries int, expectedResponses sets.String) { ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHTTPPort)) - // The current versions of curl included in CentOS and RHEL distros - // misinterpret square brackets around IPv6 as globbing, so use the -g - // argument to disable globbing to handle the IPv6 case. - cmd := fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=%s&protocol=%s&host=%s&port=%d&tries=1'", - ipPort, - dialCommand, - protocol, - targetIP, - targetPort) + cmd := makeCURLDialCommand(ipPort, dialCommand, protocol, targetIP, targetPort) responses := sets.NewString() for i := 0; i < maxTries; i++ { - stdout, stderr, err := config.f.ExecShellInPodWithFullOutput(config.TestContainerPod.Name, cmd) + resp, err := config.GetResponseFromContainer(protocol, dialCommand, containerIP, targetIP, containerHTTPPort, targetPort) if err != nil { // A failure to kubectl exec counts as a try, not a hard fail. // Also note that we will keep failing for maxTries in tests where // we confirm unreachability. - framework.Logf("Failed to execute %q: %v, stdout: %q, stderr %q", cmd, err, stdout, stderr) - } else { - var output map[string][]string - if err := json.Unmarshal([]byte(stdout), &output); err != nil { - framework.Logf("WARNING: Failed to unmarshal curl response. Cmd %v run in %v, output: %s, err: %v", - cmd, config.TestContainerPod.Name, stdout, err) - continue - } - - for _, response := range output["responses"] { - trimmed := strings.TrimSpace(response) - if trimmed != "" { - responses.Insert(trimmed) - } + framework.Logf("GetResponseFromContainer: %s", err) + continue + } + for _, response := range resp.Responses { + trimmed := strings.TrimSpace(response) + if trimmed != "" { + responses.Insert(trimmed) } } framework.Logf("Waiting for responses: %v", expectedResponses.Difference(responses)) @@ -294,14 +297,7 @@ func (config *NetworkingTestConfig) GetEndpointsFromTestContainer(protocol, targ // we don't see any endpoints, the test fails. func (config *NetworkingTestConfig) GetEndpointsFromContainer(protocol, containerIP, targetIP string, containerHTTPPort, targetPort, tries int) (sets.String, error) { ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHTTPPort)) - // The current versions of curl included in CentOS and RHEL distros - // misinterpret square brackets around IPv6 as globbing, so use the -g - // argument to disable globbing to handle the IPv6 case. - cmd := fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=1'", - ipPort, - protocol, - targetIP, - targetPort) + cmd := makeCURLDialCommand(ipPort, "hostName", protocol, targetIP, targetPort) eps := sets.NewString() @@ -314,14 +310,14 @@ func (config *NetworkingTestConfig) GetEndpointsFromContainer(protocol, containe framework.Logf("Failed to execute %q: %v, stdout: %q, stderr: %q", cmd, err, stdout, stderr) } else { framework.Logf("Tries: %d, in try: %d, stdout: %v, stderr: %v, command run in: %#v", tries, i, stdout, stderr, config.TestContainerPod) - var output map[string][]string + var output NetexecDialResponse if err := json.Unmarshal([]byte(stdout), &output); err != nil { framework.Logf("WARNING: Failed to unmarshal curl response. Cmd %v run in %v, output: %s, err: %v", cmd, config.TestContainerPod.Name, stdout, err) continue } - for _, hostName := range output["responses"] { + for _, hostName := range output.Responses { trimmed := strings.TrimSpace(hostName) if trimmed != "" { eps.Insert(trimmed) @@ -334,6 +330,50 @@ func (config *NetworkingTestConfig) GetEndpointsFromContainer(protocol, containe return eps, nil } +// GetResponseFromContainer executes a curl via kubectl exec in a container. +func (config *NetworkingTestConfig) GetResponseFromContainer(protocol, dialCommand, containerIP, targetIP string, containerHTTPPort, targetPort int) (NetexecDialResponse, error) { + ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHTTPPort)) + cmd := makeCURLDialCommand(ipPort, dialCommand, protocol, targetIP, targetPort) + + stdout, stderr, err := config.f.ExecShellInPodWithFullOutput(config.TestContainerPod.Name, cmd) + if err != nil { + return NetexecDialResponse{}, fmt.Errorf("failed to execute %q: %v, stdout: %q, stderr: %q", cmd, err, stdout, stderr) + } + + var output NetexecDialResponse + if err := json.Unmarshal([]byte(stdout), &output); err != nil { + return NetexecDialResponse{}, fmt.Errorf("failed to unmarshal curl response. Cmd %v run in %v, output: %s, err: %v", + cmd, config.TestContainerPod.Name, stdout, err) + } + return output, nil +} + +// GetResponseFromTestContainer executes a curl via kubectl exec in a test container. +func (config *NetworkingTestConfig) GetResponseFromTestContainer(protocol, dialCommand, targetIP string, targetPort int) (NetexecDialResponse, error) { + return config.GetResponseFromContainer(protocol, dialCommand, config.TestContainerPod.Status.PodIP, targetIP, testContainerHTTPPort, targetPort) +} + +// GetHTTPCodeFromTestContainer executes a curl via kubectl exec in a test container and returns the status code. +func (config *NetworkingTestConfig) GetHTTPCodeFromTestContainer(path, targetIP string, targetPort int) (int, error) { + cmd := fmt.Sprintf("curl -g -q -s -o /dev/null -w %%{http_code} http://%s:%d%s", + targetIP, + targetPort, + path) + stdout, stderr, err := config.f.ExecShellInPodWithFullOutput(config.TestContainerPod.Name, cmd) + // We only care about the status code reported by curl, + // and want to return any other errors, such as cannot execute command in the Pod. + // If curl failed to connect to host, it would exit with code 7, which makes `ExecShellInPodWithFullOutput` + // return a non-nil error and output "000" to stdout. + if err != nil && len(stdout) == 0 { + return 0, fmt.Errorf("failed to execute %q: %v, stderr: %q", cmd, err, stderr) + } + code, err := strconv.Atoi(stdout) + if err != nil { + return 0, fmt.Errorf("failed to parse status code returned by healthz endpoint: %w, code: %s", err, stdout) + } + return code, nil +} + // DialFromNode executes a tcp or udp request based on protocol via kubectl exec // in a test container running with host networking. // - minTries is the minimum number of curl attempts required before declaring diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go index 9b424de07bd7..beb31fdfb4df 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go @@ -19,6 +19,7 @@ package pod import ( "context" "fmt" + "runtime" "time" v1 "k8s.io/api/core/v1" @@ -179,7 +180,7 @@ func MakeSecPod(podConfig *Config) (*v1.Pod, error) { podConfig.Command = "trap exit TERM; while true; do sleep 1; done" } podName := "pod-" + string(uuid.NewUUID()) - if podConfig.FsGroup == nil { + if podConfig.FsGroup == nil && runtime.GOOS != "windows" { podConfig.FsGroup = func(i int64) *int64 { return &i }(1000) @@ -239,7 +240,9 @@ func MakeSecPod(podConfig *Config) (*v1.Pod, error) { podSpec.Spec.Containers[0].VolumeMounts = volumeMounts podSpec.Spec.Containers[0].VolumeDevices = volumeDevices podSpec.Spec.Volumes = volumes - podSpec.Spec.SecurityContext.SELinuxOptions = podConfig.SeLinuxLabel + if runtime.GOOS != "windows" { + podSpec.Spec.SecurityContext.SELinuxOptions = podConfig.SeLinuxLabel + } SetNodeSelection(&podSpec.Spec, podConfig.NodeSelection) return podSpec, nil diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go index 9fac26bb95e1..a9c29526bd61 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go @@ -48,7 +48,7 @@ func DeletePodOrFail(c clientset.Interface, ns, name string) { } // DeletePodWithWait deletes the passed-in pod and waits for the pod to be terminated. Resilient to the pod -// not existing. Also waits for all owned resources to be deleted. +// not existing. func DeletePodWithWait(c clientset.Interface, pod *v1.Pod) error { if pod == nil { return nil @@ -57,17 +57,10 @@ func DeletePodWithWait(c clientset.Interface, pod *v1.Pod) error { } // DeletePodWithWaitByName deletes the named and namespaced pod and waits for the pod to be terminated. Resilient to the pod -// not existing. Also waits for all owned resources to be deleted. +// not existing. func DeletePodWithWaitByName(c clientset.Interface, podName, podNamespace string) error { e2elog.Logf("Deleting pod %q in namespace %q", podName, podNamespace) - deletionPolicy := metav1.DeletePropagationForeground - err := c.CoreV1().Pods(podNamespace).Delete(context.TODO(), podName, - metav1.DeleteOptions{ - // If the pod is the owner of some resources (like ephemeral inline volumes), - // then we want to be sure that those are also gone before we return. - // Blocking pod deletion via metav1.DeletePropagationForeground achieves that. - PropagationPolicy: &deletionPolicy, - }) + err := c.CoreV1().Pods(podNamespace).Delete(context.TODO(), podName, metav1.DeleteOptions{}) if err != nil { if apierrors.IsNotFound(err) { return nil // assume pod was already deleted diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go index 30c1504c2200..155a4e74984e 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go @@ -30,7 +30,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" - errorsutil "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" @@ -352,22 +351,6 @@ func logPodTerminationMessages(pods []v1.Pod) { } } -// LogPodLogs will logs the pod's logs. -func LogPodLogs(c clientset.Interface, pods []v1.Pod) error { - var errs []error - for _, pod := range pods { - for _, container := range pod.Spec.Containers { - logData, err := GetPodLogs(c, pod.Namespace, pod.Name, container.Name) - if err != nil { - errs = append(errs, fmt.Errorf("%s[%s].container[%s].error=%v", pod.Name, pod.Namespace, container.Name, err)) - continue - } - e2elog.Logf("%s[%s].container[%s].log\n%s", pod.Name, pod.Namespace, container.Name, logData) - } - } - return errorsutil.NewAggregate(errs) -} - // DumpAllPodInfoForNamespace logs all pod information for a given namespace. func DumpAllPodInfoForNamespace(c clientset.Interface, namespace string) { pods, err := c.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{}) @@ -376,9 +359,6 @@ func DumpAllPodInfoForNamespace(c clientset.Interface, namespace string) { } LogPodStates(pods.Items) logPodTerminationMessages(pods.Items) - if err := LogPodLogs(c, pods.Items); err != nil { - e2elog.Logf("unable to fetch logs for pods: %v", err) - } } // FilterNonRestartablePods filters out pods that will never get recreated if diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/service/BUILD b/vendor/k8s.io/kubernetes/test/e2e/framework/service/BUILD index 43be89af1c31..3af1bb6cf31a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/service/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/service/BUILD @@ -13,6 +13,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/api/discovery/v1beta1:go_default_library", "//staging/src/k8s.io/api/policy/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/service/jig.go b/vendor/k8s.io/kubernetes/test/e2e/framework/service/jig.go index caa383a22975..5eaf83b7523c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/service/jig.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/service/jig.go @@ -28,6 +28,7 @@ import ( "github.com/onsi/ginkgo" v1 "k8s.io/api/core/v1" + discoveryv1beta1 "k8s.io/api/discovery/v1beta1" policyv1beta1 "k8s.io/api/policy/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -260,21 +261,42 @@ func (j *TestJig) CreateLoadBalancerService(timeout time.Duration, tweak func(sv // GetEndpointNodes returns a map of nodenames:external-ip on which the // endpoints of the Service are running. func (j *TestJig) GetEndpointNodes() (map[string][]string, error) { - nodes, err := e2enode.GetBoundedReadySchedulableNodes(j.Client, MaxNodesForEndpointsTests) + return j.GetEndpointNodesWithIP(v1.NodeExternalIP) +} + +// GetEndpointNodesWithIP returns a map of nodenames: on which the +// endpoints of the Service are running. +func (j *TestJig) GetEndpointNodesWithIP(addressType v1.NodeAddressType) (map[string][]string, error) { + nodes, err := j.ListNodesWithEndpoint() + if err != nil { + return nil, err + } + nodeMap := map[string][]string{} + for _, node := range nodes { + nodeMap[node.Name] = e2enode.GetAddresses(&node, addressType) + } + return nodeMap, nil +} + +// ListNodesWithEndpoint returns a list of nodes on which the +// endpoints of the given Service are running. +func (j *TestJig) ListNodesWithEndpoint() ([]v1.Node, error) { + nodeNames, err := j.GetEndpointNodeNames() if err != nil { return nil, err } - epNodes, err := j.GetEndpointNodeNames() + ctx := context.TODO() + allNodes, err := j.Client.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { return nil, err } - nodeMap := map[string][]string{} - for _, n := range nodes.Items { - if epNodes.Has(n.Name) { - nodeMap[n.Name] = e2enode.GetAddresses(&n, v1.NodeExternalIP) + epNodes := make([]v1.Node, 0, nodeNames.Len()) + for _, node := range allNodes.Items { + if nodeNames.Has(node.Name) { + epNodes = append(epNodes, node) } } - return nodeMap, nil + return epNodes, nil } // GetEndpointNodeNames returns a string set of node names on which the @@ -331,6 +353,8 @@ func (j *TestJig) waitForAvailableEndpoint(timeout time.Duration) error { endpointSelector := fields.OneTermEqualSelector("metadata.name", j.Name) stopCh := make(chan struct{}) endpointAvailable := false + endpointSliceAvailable := false + var controller cache.Controller _, controller = cache.NewInformer( &cache.ListWatch{ @@ -369,8 +393,54 @@ func (j *TestJig) waitForAvailableEndpoint(timeout time.Duration) error { go controller.Run(stopCh) + // If EndpointSlice API is enabled, then validate if appropriate EndpointSlice objects were also create/updated/deleted. + if _, err := j.Client.Discovery().ServerResourcesForGroupVersion(discoveryv1beta1.SchemeGroupVersion.String()); err == nil { + var esController cache.Controller + _, esController = cache.NewInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + options.LabelSelector = "kubernetes.io/service-name=" + j.Name + obj, err := j.Client.DiscoveryV1beta1().EndpointSlices(j.Namespace).List(context.TODO(), options) + return runtime.Object(obj), err + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + options.LabelSelector = "kubernetes.io/service-name=" + j.Name + return j.Client.DiscoveryV1beta1().EndpointSlices(j.Namespace).Watch(context.TODO(), options) + }, + }, + &discoveryv1beta1.EndpointSlice{}, + 0, + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + if es, ok := obj.(*discoveryv1beta1.EndpointSlice); ok { + // TODO: currently we only consider addreses in 1 slice, but services with + // a large number of endpoints (>1000) may have multiple slices. Some slices + // with only a few addresses. We should check the addresses in all slices. + if len(es.Endpoints) > 0 && len(es.Endpoints[0].Addresses) > 0 { + endpointSliceAvailable = true + } + } + }, + UpdateFunc: func(old, cur interface{}) { + if es, ok := cur.(*discoveryv1beta1.EndpointSlice); ok { + // TODO: currently we only consider addreses in 1 slice, but services with + // a large number of endpoints (>1000) may have multiple slices. Some slices + // with only a few addresses. We should check the addresses in all slices. + if len(es.Endpoints) > 0 && len(es.Endpoints[0].Addresses) > 0 { + endpointSliceAvailable = true + } + } + }, + }, + ) + + go esController.Run(stopCh) + + } else { + endpointSliceAvailable = true + } err := wait.Poll(1*time.Second, timeout, func() (bool, error) { - return endpointAvailable, nil + return endpointAvailable && endpointSliceAvailable, nil }) if err != nil { return fmt.Errorf("no subset of available IP address found for the endpoint %s within timeout %v", j.Name, timeout) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go index 01c99f908ae8..ff0dec92f77d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go @@ -213,6 +213,13 @@ func SkipUnlessNodeOSDistroIs(supportedNodeOsDistros ...string) { } } +// SkipUnlessNodeOSArchIs skips if the node OS distro is not included in the supportedNodeOsArchs. +func SkipUnlessNodeOSArchIs(supportedNodeOsArchs ...string) { + if !framework.NodeOSArchIs(supportedNodeOsArchs...) { + skipInternalf(1, "Only supported for node OS arch %v (not %s)", supportedNodeOsArchs, framework.TestContext.NodeOSArch) + } +} + // SkipIfNodeOSDistroIs skips if the node OS distro is included in the unsupportedNodeOsDistros. func SkipIfNodeOSDistroIs(unsupportedNodeOsDistros ...string) { if framework.NodeOSDistroIs(unsupportedNodeOsDistros...) { diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go b/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go index ddca9d4cc113..b0a8a9f97ab7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go @@ -116,6 +116,7 @@ type TestContextType struct { ImageServiceEndpoint string MasterOSDistro string NodeOSDistro string + NodeOSArch string VerifyServiceAccount bool DeleteNamespace bool DeleteNamespaceOnFailure bool @@ -324,6 +325,7 @@ func RegisterClusterFlags(flags *flag.FlagSet) { flags.StringVar(&TestContext.Prefix, "prefix", "e2e", "A prefix to be added to cloud resources created during testing.") flags.StringVar(&TestContext.MasterOSDistro, "master-os-distro", "debian", "The OS distribution of cluster master (debian, ubuntu, gci, coreos, or custom).") flags.StringVar(&TestContext.NodeOSDistro, "node-os-distro", "debian", "The OS distribution of cluster VM instances (debian, ubuntu, gci, coreos, or custom).") + flags.StringVar(&TestContext.NodeOSArch, "node-os-arch", "amd64", "The OS architecture of cluster VM instances (amd64, arm64, or custom).") flags.StringVar(&TestContext.ClusterDNSDomain, "dns-domain", "cluster.local", "The DNS Domain of the cluster.") // TODO: Flags per provider? Rename gce-project/gce-zone? diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/util.go b/vendor/k8s.io/kubernetes/test/e2e/framework/util.go index 7bf5ea92583d..c5831027faa7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/util.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/util.go @@ -203,6 +203,16 @@ func NodeOSDistroIs(supportedNodeOsDistros ...string) bool { return false } +// NodeOSArchIs returns true if the node OS arch is included in the supportedNodeOsArchs. Otherwise false. +func NodeOSArchIs(supportedNodeOsArchs ...string) bool { + for _, arch := range supportedNodeOsArchs { + if strings.EqualFold(arch, TestContext.NodeOSArch) { + return true + } + } + return false +} + // DeleteNamespaces deletes all namespaces that match the given delete and skip filters. // Filter is by simple strings.Contains; first skip filter, then delete filter. // Returns the list of deleted namespaces or an error. @@ -1056,13 +1066,13 @@ func NodeHasTaint(c clientset.Interface, nodeName string, taint *v1.Taint) (bool // RunHostCmd runs the given cmd in the context of the given pod using `kubectl exec` // inside of a shell. func RunHostCmd(ns, name, cmd string) (string, error) { - return RunKubectl(ns, "exec", fmt.Sprintf("--namespace=%v", ns), name, "--", "/bin/sh", "-x", "-c", cmd) + return RunKubectl(ns, "exec", name, "--", "/bin/sh", "-x", "-c", cmd) } // RunHostCmdWithFullOutput runs the given cmd in the context of the given pod using `kubectl exec` // inside of a shell. It will also return the command's stderr. func RunHostCmdWithFullOutput(ns, name, cmd string) (string, string, error) { - return RunKubectlWithFullOutput(ns, "exec", fmt.Sprintf("--namespace=%v", ns), name, "--", "/bin/sh", "-x", "-c", cmd) + return RunKubectlWithFullOutput(ns, "exec", name, "--", "/bin/sh", "-x", "-c", cmd) } // RunHostCmdOrDie calls RunHostCmd and dies on error. @@ -1140,7 +1150,7 @@ func AllNodesReady(c clientset.Interface, timeout time.Duration) error { // LookForStringInLog looks for the given string in the log of a specific pod container func LookForStringInLog(ns, podName, container, expectedString string, timeout time.Duration) (result string, err error) { return lookForString(expectedString, timeout, func() string { - return RunKubectlOrDie(ns, "logs", podName, container, fmt.Sprintf("--namespace=%v", ns)) + return RunKubectlOrDie(ns, "logs", podName, container) }) } @@ -1266,7 +1276,7 @@ func GetAllMasterAddresses(c clientset.Interface) []string { // CreateEmptyFileOnPod creates empty file at given path on the pod. // TODO(alejandrox1): move to subpkg pod once kubectl methods have been refactored. func CreateEmptyFileOnPod(namespace string, podName string, filePath string) error { - _, err := RunKubectl(namespace, "exec", fmt.Sprintf("--namespace=%s", namespace), podName, "--", "/bin/sh", "-c", fmt.Sprintf("touch %s", filePath)) + _, err := RunKubectl(namespace, "exec", podName, "--", "/bin/sh", "-c", fmt.Sprintf("touch %s", filePath)) return err } @@ -1274,10 +1284,10 @@ func CreateEmptyFileOnPod(namespace string, podName string, filePath string) err func DumpDebugInfo(c clientset.Interface, ns string) { sl, _ := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{LabelSelector: labels.Everything().String()}) for _, s := range sl.Items { - desc, _ := RunKubectl(ns, "describe", "po", s.Name, fmt.Sprintf("--namespace=%v", ns)) + desc, _ := RunKubectl(ns, "describe", "po", s.Name) Logf("\nOutput of kubectl describe %v:\n%v", s.Name, desc) - l, _ := RunKubectl(ns, "logs", s.Name, fmt.Sprintf("--namespace=%v", ns), "--tail=100") + l, _ := RunKubectl(ns, "logs", s.Name, "--tail=100") Logf("\nLast 100 log lines of %v:\n%v", s.Name, l) } } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go b/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go index c4a2c75557d0..7e687f3ef8af 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go @@ -173,6 +173,23 @@ func NewGlusterfsServer(cs clientset.Interface, namespace string) (config TestCo } pod, ip = CreateStorageServer(cs, config) + service := &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.Prefix + "-server", + }, + Spec: v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + Protocol: v1.ProtocolTCP, + Port: 24007, + }, + }, + }, + } + + _, err := cs.CoreV1().Services(namespace).Create(context.TODO(), service, metav1.CreateOptions{}) + framework.ExpectNoError(err, "failed to create service for Gluster server") + ginkgo.By("creating Gluster endpoints") endpoints := &v1.Endpoints{ TypeMeta: metav1.TypeMeta{ @@ -199,7 +216,7 @@ func NewGlusterfsServer(cs clientset.Interface, namespace string) (config TestCo }, }, } - _, err := cs.CoreV1().Endpoints(namespace).Create(context.TODO(), endpoints, metav1.CreateOptions{}) + _, err = cs.CoreV1().Endpoints(namespace).Create(context.TODO(), endpoints, metav1.CreateOptions{}) framework.ExpectNoError(err, "failed to create endpoints for Gluster server") return config, pod, ip diff --git a/vendor/k8s.io/kubernetes/test/e2e/generated/.gitignore b/vendor/k8s.io/kubernetes/test/e2e/generated/.gitignore new file mode 100644 index 000000000000..78d1d4e5edd7 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/generated/.gitignore @@ -0,0 +1,2 @@ +# Ensure that bindata is not ignored to ensure openshift/origin can vendor it. +!bindata.go diff --git a/vendor/k8s.io/kubernetes/test/e2e/generated/bindata.go b/vendor/k8s.io/kubernetes/test/e2e/generated/bindata.go index cc397a04ebcd..bd99634bfe77 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/generated/bindata.go +++ b/vendor/k8s.io/kubernetes/test/e2e/generated/bindata.go @@ -445,7 +445,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _testConformanceTestdataOwners = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4c\x8f\x41\x6b\xc3\x30\x0c\x85\xef\xfe\x15\x82\x9e\x93\xf4\xb4\x8d\xdc\x77\xdd\x60\x1d\xec\x58\x64\x47\x89\xb5\xc5\x96\x91\xd5\x74\xf9\xf7\xa3\xc9\x28\xbd\xbd\x4f\x7c\xe2\xf1\x0e\x70\x22\x02\x8b\x04\xef\x5f\x6f\xaf\x1f\x27\x18\x24\x54\x40\x83\x68\x56\x6a\xdf\x75\x93\xb4\x3f\x2f\xb5\x65\xe9\xe4\x9a\x49\xab\x73\x07\xf8\x14\xf0\x04\x37\x1e\xc0\xaf\x50\x79\x6a\x50\x43\x64\xa3\x60\x17\xa5\xd6\x49\x31\x96\x5c\x7b\x07\x90\xe5\x5c\x50\x29\xdb\x79\xff\xef\xc1\xf4\x42\x4e\x69\x61\xba\xde\xd8\x01\x34\xe0\x27\xc5\x6c\xc7\xa7\xe3\xf3\x86\x35\xa1\x1a\x69\x98\x71\x35\xc9\xfb\xa9\xf0\x38\xfe\x96\x2d\x1b\x27\xb1\xb8\xd6\xb0\xd1\xc0\xa9\x6e\xe1\x5b\x62\xf6\x34\x63\x42\xe5\xe0\xb0\x14\x95\xe5\xde\x10\x24\x8f\xa2\x09\x73\xa0\xc6\x53\xc4\x85\x45\x9b\xbb\xe3\x66\xf4\x34\xff\xab\xa8\x84\xdd\x83\xbf\xf7\xf3\xd4\x3d\x8e\x74\x7f\x01\x00\x00\xff\xff\x52\x92\x9f\xdf\x3a\x01\x00\x00") +var _testConformanceTestdataOwners = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4c\x8f\xc1\x6a\xc3\x30\x0c\x86\xef\x7e\x0a\x41\xcf\x89\xaf\x23\xf7\x5d\x37\x58\x07\x3b\x16\xd9\x51\x62\x6d\xb1\x65\x64\x35\x5d\xde\x7e\x34\x19\xa5\xb7\xff\x13\x9f\x24\xfe\x13\x9c\x89\xc0\x12\xc1\xfb\xd7\xdb\xeb\xc7\x19\x46\x89\x0d\xd0\x20\x99\xd5\x36\x78\x3f\x4b\xff\xf3\xd2\x7a\x16\x2f\xb7\x42\xda\x9c\x3b\xc1\xa7\x40\x20\xb8\xf3\x08\x61\x83\xc6\x73\x87\x1a\x13\x1b\x45\xbb\x2a\xf5\x4e\xaa\xb1\x94\x36\x38\x80\x22\x97\x8a\x4a\xc5\x2e\xc7\xfe\x00\xa6\x57\x72\x4a\x2b\xd3\xed\xce\x0e\xa0\x83\x96\x51\x8d\x34\x2e\xb8\x99\x94\x63\x54\x79\x9a\x7e\xeb\x9e\x8d\xb3\x58\xda\x5a\xdc\x69\xe4\xdc\xf6\xf0\x2d\xa9\x04\x5a\x30\xa3\x72\x74\x58\xab\xca\xfa\x38\x19\xa5\x4c\xa2\x19\x4b\xa4\x2e\x50\xc2\x95\x45\xbb\x87\xe3\x16\x0c\xb4\xfc\xab\xa8\x84\xfe\xc9\x3f\xfe\xf3\xec\x9f\x5b\xb9\xbf\x00\x00\x00\xff\xff\xbd\x28\x57\xaf\x2b\x01\x00\x00") func testConformanceTestdataOwnersBytes() ([]byte, error) { return bindataRead( @@ -465,7 +465,7 @@ func testConformanceTestdataOwners() (*asset, error) { return a, nil } -var _testConformanceTestdataConformanceYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1c\xb7\xb1\x38\x8c\xbf\xcf\xa7\x40\xf9\x0d\xe3\x5f\x2d\x97\x94\x7c\x4b\x9c\xbf\xff\x55\x0a\x25\x27\x3a\xc7\x96\x18\x51\x8e\x5f\xf8\xb8\xf4\xc3\xce\x60\xb9\x08\x67\x07\x93\x01\x86\xd4\x9e\xa7\x9e\xef\xfe\x14\xba\x1b\xb7\xb9\xec\xce\x5e\x49\x39\x3e\x27\x95\x88\x3b\x33\x8d\x46\x77\xa3\xd1\x68\xf4\xe5\x9c\x19\xa1\x4d\xc9\x97\xe2\x5b\x76\xad\x72\xf6\x83\x9c\x8b\x6c\x95\x15\x62\xc2\x2a\xa5\x0d\xd3\x86\xd7\x86\x89\x8f\x22\x63\x0b\xa5\xee\xfe\xc0\x58\xa6\x72\x81\xef\x9f\xfd\x72\xf7\x27\x3d\x95\xea\x57\x76\xa5\x4a\xc3\x65\x29\xea\xf0\x3d\xfb\xbb\x52\x77\xec\x61\x21\x4a\x96\xd5\x82\x1b\xc1\x38\xab\x54\xce\x1e\xa4\x59\xb0\xc2\xbf\x45\x40\x19\xd3\x0b\xd5\x14\x39\x8c\xd4\x18\x01\x83\xb7\xc6\x66\x55\xad\x2a\x51\x17\x2b\xf6\xcb\x1b\x95\x8b\x2b\x55\xce\x55\xbd\xe4\x65\x26\x7e\x65\xbf\xc4\x7f\x9d\xfd\x81\xb1\x5c\xe8\xac\x96\x95\x91\xaa\xfc\x96\xfd\x6c\xb1\xe0\xf1\x84\x16\xbc\xcc\x0b\x51\x33\xa9\x99\xae\x44\x26\xe7\x52\xe4\x4c\x96\xcc\x2c\x04\xcb\xfc\x64\x02\x9a\x8d\x96\xe5\x2d\xe0\xc9\xd9\xd9\xab\x8f\x22\x3b\x63\x3c\xb3\xc0\x27\xf6\x13\xfc\xce\xc1\xfc\xf1\xa7\x9b\xf7\x6c\x26\x98\x2c\xef\xd5\x9d\xc8\x19\x9f\x1b\x51\xc3\x1b\x38\xb6\x9a\xa7\xc3\x4c\x01\xee\x0b\xa6\x45\x7d\x2f\x6a\x20\x92\xd4\x44\xb4\x9c\x99\x05\x37\xec\x41\x16\x05\x3e\x67\x0b\x63\x2a\x56\x8b\x7f\x37\x42\x1b\x3d\x09\xb4\xd5\x22\x53\x65\xee\x49\x4c\xb8\xf6\xcd\x05\x27\xbc\x92\xe5\x6d\x4a\x13\x18\x09\x91\xd6\x88\x6e\x40\x28\xcc\xdf\x4e\xfe\x05\x4c\x9d\x19\xc5\xee\x79\x21\x73\x8b\x00\x7c\x6c\x3f\x8a\x00\x4a\xed\xd8\x99\xdb\x39\xd6\xa2\x10\x5c\x8b\x6f\xd9\xfd\xb3\xe9\x9f\xff\xc0\xd8\x5c\x16\xe2\x5b\x10\xbf\x0b\xf1\x5c\x5c\x64\x6a\xb9\x54\xe5\x85\xc7\xf3\x83\xe5\xf9\xf4\x56\xfd\x61\x9c\x88\x02\x5d\x1e\x49\x44\xfd\xd8\x4f\x45\x44\xff\x6e\x4c\xf5\x37\x61\xfe\xb3\x64\x34\x12\x47\x80\xfc\x48\x22\x59\x0b\x6d\x54\xf5\x18\x2a\xb3\x3d\xf2\xfe\xd2\x58\x8b\x73\x00\x79\x4a\x75\x39\x13\x73\x55\x8b\x16\x68\xa9\x99\x11\xf5\x52\x96\x9c\x38\xf7\x78\xc2\xe8\x68\x72\x20\x75\xe9\xc0\x9d\x4e\x32\x1f\x41\x53\xb6\x47\x7e\x22\x92\x49\x6a\xf2\x3f\x4c\x38\x87\xf5\xe4\x11\x65\x31\x08\xd5\xbb\xa6\x34\x72\x29\x26\xec\x3d\xd1\x4c\xaa\xf2\x47\xa1\x35\xbf\x15\x13\x36\xaf\xd5\x92\x15\xea\x96\xa9\xc6\x54\x0d\xec\x43\xba\xc9\x32\x21\x72\x3b\x41\x3f\xff\x8d\x92\x4b\x83\xb0\x59\xc1\xb3\xbb\x99\xfa\x08\x98\x30\xbb\x08\x3d\xa3\x22\x6a\xa2\xb8\x02\x31\x6a\x51\x29\xbb\xcf\x04\xdc\xd8\x12\x91\x63\xbf\xfc\x20\xcb\xe6\xe3\xdb\xb2\x58\xfd\xca\xb8\x66\x62\x59\x99\x15\xae\x09\x4b\x55\x42\x53\x33\x5e\xe6\x3d\x53\xbb\x56\x85\xcc\x56\x30\xc4\xf7\xbc\x28\x66\x3c\xbb\x7b\xaf\x7e\x50\xb7\xfa\x6d\xf9\xaa\xae\x15\x0a\xb0\x30\x5b\xaf\x87\xb3\xab\xce\x7a\xe4\x65\xb4\x6f\x07\x9a\x9c\x9d\x69\x47\x55\xa9\x59\x2d\x32\x55\xe7\xb0\x56\x00\x29\x4b\x73\x8b\x79\x20\x8a\xf8\x28\x8d\xc6\x69\x69\x3d\x6f\x8a\x62\x05\xe0\x55\x63\xec\x08\xc2\x22\x3d\xc5\xe5\x38\xb0\x12\x26\x28\x5d\x1d\x52\xe0\xa2\x5a\xf0\x7b\xc1\x4a\x05\x1f\x8b\xd2\x58\x8a\x46\x0c\x41\x62\x4e\x63\x9a\x7f\xcb\xae\x78\x59\x2a\x03\x50\x97\xaa\x29\x0d\x08\xa2\xb6\xab\xfd\x67\x59\xe6\xea\x41\x87\xc9\xea\xe9\x59\x4b\x70\x9f\x7d\x35\x28\xb9\x35\x0a\xcb\x3e\x22\x6b\x01\x3f\x59\x61\x0d\x18\xfe\x56\xa4\x95\xe3\x74\x2c\xf2\xa9\x2a\xde\x4d\x68\x13\x41\x15\xf9\x64\x50\x68\x97\xdc\x64\x0b\xc4\xdb\x8d\x6b\x65\xd7\x13\x38\x15\x58\x00\x8b\x42\xfb\xe4\x04\xd6\x4f\xff\x4c\xa7\xfa\x16\x90\x9e\x73\x59\x3c\x41\x19\x8e\x10\x95\xf3\x4f\x50\x6c\x87\x94\xac\x83\x38\x46\xa9\xc6\x94\x42\x55\xd8\x15\x50\x2b\x9b\xe2\x63\x25\x32\x4b\x75\x42\xc7\xe3\xd2\x62\x3f\xf2\xff\x13\x10\xdc\x6b\x6e\x16\x13\x56\xaa\xf2\xbc\x56\xca\xb0\x46\x8b\x1a\x88\x69\x7f\xc9\xc5\x9c\x37\x05\x6e\x0d\x15\x07\x7b\xe9\x71\xc5\xb5\x5f\x3c\xb9\x59\x38\x11\xe4\xda\x4f\x05\xe0\xfa\xe9\x70\xc3\x78\x3c\x27\x98\xcf\x41\x24\x36\x9a\x90\x51\xac\x6e\x4a\x26\x01\x0f\xde\x22\x2a\xbe\x0d\x58\x65\x8d\x36\x6a\x39\x34\x15\x2d\xcc\x14\x0e\x19\xb5\xc8\x65\x2d\x32\x83\xa6\x26\x09\x9c\x51\x64\x54\xaa\x7b\x69\xe5\x8e\xf8\xc2\x12\xed\x4c\xc2\xbe\xc6\x9e\x06\xa3\xbc\x97\xde\x41\xe0\xc9\x8c\xed\x0a\x7d\xa1\x6e\x6f\xc3\x79\xc0\xa3\x42\xd3\xb2\x18\xb5\x4c\x8c\xf7\x1c\x3e\xf0\x3f\x01\xe4\xbc\x11\x76\x36\x8d\x86\x2d\xfe\xec\xac\x91\xf9\xd9\x19\x30\xab\x29\xf9\xac\x80\x87\x8f\xb4\x4c\xde\x09\xf4\x6b\xa0\xe6\x9b\x00\x37\xae\x17\x5c\x0b\xbd\xe3\x12\x00\x0b\x01\x60\xe2\x89\x22\x92\x99\x05\x47\x51\xa5\x3d\x16\x8f\x78\x56\x8c\xfc\x7e\xe8\xc9\xaf\x0d\x37\x8d\xde\x5a\x6a\x5f\xa3\xd7\xa9\xa6\x49\x55\x30\x29\xb7\x62\x8c\x62\x67\x2f\x8a\x07\xbe\xd2\x67\x38\x4f\x77\x36\xa3\xd7\x45\x0e\xc8\x77\xf6\xf2\xd7\xf3\x1e\x80\x67\x6f\xcb\xef\xb9\x2c\x9a\x5a\xb4\x80\x39\x50\xaa\x2c\x56\x76\x15\x4b\xd3\xb5\x0f\x70\xc2\x76\xd1\xfc\xaf\xa8\x15\xd0\x03\x68\x3d\x1d\x9e\xc0\xd9\x1b\x71\x2f\xea\x68\x2c\x00\x59\xda\x1f\x93\x29\x4c\xd9\x8b\xa2\xb0\x30\xb4\x3d\x64\xd6\x42\x20\x57\x32\xcb\x51\xc4\xf1\x5e\xd4\x72\xbe\x4a\x86\xc9\xac\xec\x21\x92\x3c\xb3\x5a\x5e\x96\xb7\xc5\xaa\x7d\x72\x7b\xf6\xc5\xb6\xf2\xf6\x52\x65\x77\xa2\x0e\x22\xa0\x27\xa4\x1b\xea\xdb\x66\x29\x70\xc8\x3e\x19\xa3\xef\x82\xec\x3b\x61\x99\x09\xe6\xd6\x8b\xba\x17\x75\x2d\x73\x3c\x4a\xcb\x25\xbf\x15\x76\x27\x8a\xf5\xb8\x1f\x85\xfd\x31\x27\x44\x96\xf9\xe7\x5b\xcb\xd4\x4b\x52\xa3\x76\xaa\xa0\x5f\xcb\x9c\xe1\x1e\x68\x47\x26\xc8\x80\x00\x13\xa5\xa9\x57\x95\x92\xa5\xf1\xe2\xd0\x68\x81\x7a\x1f\xd6\x85\x65\x5e\xae\x84\x55\xdd\xc6\x1d\xbc\x5b\xba\xcb\x0d\x33\x6b\xf0\x4c\x1d\x66\x01\x63\x5a\x08\xf6\x43\x80\x09\x83\x78\x42\xe0\xca\x73\x3e\x8c\xf1\xe7\x6e\x9c\xc2\x87\xc0\xa5\xb1\x6c\x24\x54\x8f\xca\x44\x47\x0e\xc7\xc2\x40\xe2\xfd\x39\x39\x8e\x89\x6f\xde\x7a\x46\x06\xfd\xe0\xd8\x60\x49\xad\xfb\x39\x38\x65\xec\x2a\x1e\xc8\x7d\xd2\xe2\x9a\x59\x88\x64\xa2\xb4\xd5\x00\x2e\xa7\xe3\x21\x5a\x0e\x27\x59\x96\xbd\x23\x1e\x64\x55\xb6\x96\xca\x26\xce\x02\x36\x6d\xee\x8e\xe1\x6c\x3a\x58\xc4\x67\x5c\x0c\x6c\x68\xcd\x76\x39\x3f\x80\xfe\x69\x65\xc0\x9e\x6d\x0f\x22\x06\x8d\x8e\xd8\xee\x78\xae\xed\x26\x98\x75\x09\xa4\x19\xaf\xc1\x76\x28\xef\x1e\x8d\xf9\x1d\xc6\x8f\xd3\xcd\x87\xe3\x88\x2c\xa5\x39\xf7\x8f\xcf\x61\x37\xd6\xe7\xbc\xaa\xce\x69\x6b\xe6\x60\xaf\x9c\x57\x6a\x48\xcb\xbe\x2e\xa5\x09\x26\x59\x97\x90\xc4\x1a\xf4\xe4\xc2\x78\x11\xff\x81\x08\xaa\x64\xdc\x99\x81\x68\x1e\x81\xc9\xbf\x9e\x03\xaf\x4a\xdd\xd4\x74\x0b\xc1\x8b\x22\x45\x03\x59\xeb\x0c\x21\x60\x4e\x51\x44\xc3\x5a\xf9\xc6\x19\xb1\xf4\x2d\xc3\x2c\x55\xed\x31\xaa\x65\xcd\x6b\x23\x8b\xc2\x9a\x8a\xa5\x35\x2a\xf1\x1c\x1e\x6c\x72\x7b\x18\xb0\x86\xf5\x4c\x38\xd7\x7c\x6a\xd1\x01\x6b\x17\x5c\xb7\xcd\x2a\xae\xd3\x79\x77\x0c\x9e\xe7\x83\x9c\xb5\x84\x0c\x7c\xdd\x9a\xad\x60\xb7\x9d\x8c\xab\x60\x3a\x9e\x92\xa9\xf6\xcd\x7b\x55\x34\xa5\xe1\xb5\x2c\x56\x1d\xcb\x17\x0c\x5e\x32\xf1\x2f\x27\xde\x0b\xa7\x57\xda\x88\xa5\xe5\xad\x5d\x82\xb7\xca\xf2\xda\xa8\x98\xa1\x8c\x97\x2b\xba\x5a\xd6\x22\x1e\x7c\x1c\x9b\x81\x10\xc7\xe2\xf2\x9c\xcb\x42\xc3\xf5\xc7\x31\x58\x0d\x4a\x09\x49\x50\x55\x6d\x66\x83\x8d\xc1\x65\x41\x97\xd5\x39\x9c\x3b\x52\xa1\xc0\xe7\x7b\x4b\x45\x3c\xb6\x63\x54\xb2\xd4\x92\x35\x9c\xcc\xcd\xfb\x05\xb5\xb5\x13\x1c\x3b\xf3\xa7\xc9\xb5\x43\xe9\xdd\xb5\x6c\x1b\xc3\xa5\xdd\x34\xf2\x66\x36\x75\x97\xb7\x1d\x9a\xce\x2a\xeb\xf8\x23\x72\x36\x57\x35\x9b\x8b\x07\xa6\xb2\xac\xa9\x6b\x51\x66\x02\xaf\x01\xaa\x5e\x4e\xa2\x84\x1e\x4b\xd5\xfe\x77\x33\x13\x85\x30\x13\xb6\x50\xda\xbc\x28\xe4\x1a\xcf\x05\xbd\x4a\xe7\xa4\x6c\x21\xf2\xa6\x40\x1f\xc5\xac\xd1\xab\x99\xfa\x08\x53\x05\x05\x15\x01\x8b\x7d\x77\x0f\xb5\x34\x68\x49\x80\x6d\xa8\xd8\x85\x30\xd9\x85\x7d\x59\x27\xce\xbb\x6d\xed\x19\xef\x6b\xeb\x45\x00\x74\x6d\xc4\xcf\xc4\x6e\xb7\x26\x37\xb8\xaa\x00\xc1\x08\x1f\xc2\x12\xfc\x6b\xe8\xa2\xd5\xd1\xbd\x19\x78\xbd\xec\xe4\xdd\x64\xd4\x3c\xba\xfe\x4e\x69\xc9\x9c\x27\x2e\x5c\xa9\xf6\x8d\x63\xc9\x5b\x97\xc2\x08\x8d\xbe\x2c\x34\x9e\xa3\x37\xe1\xc6\x45\x96\xa4\xd1\xa5\xd1\x89\x25\xba\x50\x0f\x76\x9d\x4f\xf0\x63\x8b\x9a\x2c\x73\x79\x2f\xf3\x86\x17\xce\x2d\x46\x82\xdc\x54\x95\x22\x1f\x8b\xf3\x93\xa1\xc3\x39\xd8\x59\xec\x7b\x55\x33\xb3\x00\x17\x3a\xd7\x78\x33\x0f\x5e\x41\x0d\x7e\xf5\x25\xaf\xef\x62\x2f\xdd\x16\xae\x8e\x3b\x94\xa2\x41\x39\x0c\x57\x0c\x93\xe8\xd8\xb3\x9b\x3c\x46\x67\x42\xf4\xc3\x92\x56\xa9\x6a\x59\x1a\xef\xb3\x0c\xee\x52\x60\xf2\xb6\xc2\xf7\xd7\x95\xc3\x93\xc2\xb7\x72\xbc\xec\xca\xed\x3f\x45\x5d\x07\x7b\xda\x99\x5a\x60\x67\xf9\x0b\xfe\x70\xa5\x56\xc5\x6e\x30\x51\x06\x0f\xae\x97\xc0\x03\xd2\x19\xd5\x95\x85\x6d\xe9\x5c\x08\x88\x45\xd8\x8f\xcc\x64\xf8\x80\xc2\x85\x7d\x01\x05\xb5\x45\xfc\x19\xc4\x83\x69\x49\x07\x5e\x1c\xfb\x00\x4b\x3e\x32\x92\xac\x69\x24\xa6\xec\xfd\x22\x71\x64\x27\xf4\xb5\xe7\x6d\xb7\x36\x67\x82\xb0\xe8\x38\x7d\x0e\x44\xdf\x08\x07\x5c\x4e\x27\x22\x35\xa8\x2a\x5e\x76\xc7\x3f\x0a\xb9\xbd\x17\x17\x86\x05\xff\x6d\x72\x10\x99\xa6\x4a\x26\x0a\xed\xe9\x00\x83\xe5\x13\x60\xf5\x4d\xe1\x80\xac\xf2\x37\x34\xb5\xe0\xe4\x78\x86\xcb\x18\x50\xb8\x68\x54\x6f\xcd\xb0\x00\x2a\xb0\xae\xe7\x36\xcb\xea\x63\xdc\x15\x8d\x0a\x83\x92\x21\x7f\xd8\x2d\x51\x8b\xac\xa9\xa5\x59\xe1\xa5\xf9\x47\x03\x3e\x7d\x78\xf2\x4e\xf0\xdc\x8e\xf2\x4e\x29\xf3\xbd\x2c\xc4\x8d\x9b\x32\x73\x7e\x7f\x53\x37\xb0\x9e\x04\x80\xc3\x20\x2d\xb7\x87\x7b\xf4\x61\xbb\xc2\x38\x0c\x3c\x5a\xda\xf9\x4c\xe8\xb9\xaa\x44\x1d\xae\x4c\xe9\xed\xf6\x84\x81\xe3\x60\xc2\x71\xed\xef\x32\xfc\x3a\xee\xdf\x7a\x98\x96\x65\x86\x4b\xd9\xdd\xf9\x04\x2f\x04\xee\x74\x18\xd5\x95\x5c\xa7\xeb\xc0\xf0\x73\xe0\x12\x87\x2b\xb1\x03\x0a\xd5\x92\x97\xfc\x56\xe4\x4c\x98\x0c\xec\x81\x0d\x56\xd5\x8f\xf8\xfa\x2b\x93\xfd\x1d\x36\x7b\x5a\xc1\x30\x6b\x1a\xca\x83\x0c\x36\x01\x9e\x09\x2c\xc9\x0f\x2b\x2b\x6d\x3a\xd9\xc1\xde\x08\xf3\xa0\xea\x3b\x27\x12\x73\x5e\x68\x31\x81\x15\x4e\x31\x0b\x89\xaf\x67\xad\x11\x63\x51\xc1\x28\x3f\xa5\xcd\x34\x8c\x4f\x41\x77\xd7\x71\xd0\x5d\xcf\xd0\x28\x8d\xcf\x82\x40\xb6\x71\xfc\x0e\x90\x8b\x14\x48\x8b\x62\x6a\x9e\x20\x4a\x64\x9d\xa1\xbb\x8a\x18\x32\x65\xcf\x37\x0e\x40\x77\x0c\xe4\x96\x75\xcb\x9b\x26\xde\x99\xb4\x33\x03\x70\xd2\xef\x7b\xe8\x02\x08\x5b\xc1\x9d\x21\xcc\x21\xcc\xbe\x58\x83\x99\x25\x0e\x9b\xf4\x82\xf6\x1a\x67\x26\x06\x41\x8f\x58\x6b\x7e\x9d\x65\xed\x70\xb0\xae\xc5\x59\xc6\x46\xe5\x68\xbf\x1f\x09\xfc\x07\x61\xb2\x0f\x30\x87\xf6\x2a\x03\x20\xec\xc5\xf5\xeb\xd8\x83\x7e\xcf\x65\x41\xdb\x7a\xdf\x42\xfb\x01\xbe\x59\xfb\xe5\x86\x75\xf2\x19\x09\x2a\x42\x52\xb3\x7f\x89\xcc\xa0\xf7\xe5\x56\x18\x26\xcd\x5f\x7c\xf8\x28\xfd\xe4\x8d\x39\x7f\xe1\xee\xdd\x0d\x37\x95\xc8\x5c\x90\x3f\xec\x15\x08\x34\x8a\x21\x71\x6f\xa8\x5a\xde\xca\x92\x17\xf8\xc6\x94\xfd\x54\x51\x00\x33\x21\xe2\x41\x3a\x24\x1a\x7c\x61\x18\x89\xff\x31\x1b\x30\x20\xe1\x8b\xb1\x40\xa0\xb9\x43\xe2\xda\x87\xb9\xe0\x57\xf1\xf8\x15\x3c\x6b\x0d\xdf\x0a\x3c\xd8\x92\x06\x00\x32\x8c\x8e\x7c\x20\xab\x99\x94\x06\x7e\x8b\xf1\xd0\x7c\x26\x0a\x3c\xf7\x15\x52\x1b\x7c\xa4\x13\xee\xc0\xef\x6b\xd8\x13\x9e\xd7\xc2\x34\x75\xc9\x66\xca\x02\x06\x40\x53\xf6\x12\x6d\x56\x8b\x37\x8d\x85\x62\x75\x2f\xb9\xb3\x67\x33\x55\x14\x02\x82\x9a\xff\xe2\x95\x23\x3d\xea\x0e\x1b\xcc\x1d\x7a\x05\xb6\xa4\x36\xf8\x29\xfb\xc1\x62\x85\x48\x20\xd4\x81\x69\x04\x78\x84\xfd\xbf\x1a\x6d\x88\xcc\x4b\x2e\xc1\x09\x4c\x20\xe3\xa9\xd8\x5f\x10\xee\x20\xa6\x53\xf6\x37\x61\xa2\xb7\x03\x8b\x69\x24\xab\x5e\xe6\xaa\x29\x73\x8a\xa5\xfa\xac\xbd\xa3\x7e\x33\x1c\xbf\x0c\x18\x75\x43\xe8\xf5\x84\xbd\xc8\x8c\xbc\x17\x2f\x05\xcf\x0b\x59\x8a\x1b\xe0\xf8\xd0\x86\x6a\xbf\x70\x8b\x9b\x17\x85\x7a\x80\xe0\xf2\xce\xd7\x64\xf8\x3b\xb9\xee\xec\x99\x40\x87\x6d\xf7\x4d\xce\x9a\x52\xfe\xbb\x21\xbe\x4d\xd9\x3f\x1a\x51\xaf\xc0\xdf\x63\x62\x7d\xed\x39\xeb\x7c\x3b\x5a\x58\x61\x51\x75\x2f\xc5\x9d\xaa\x97\xda\x63\x0b\x50\x86\x88\x82\x56\x1b\xd9\x60\xee\xee\x2c\x32\xcf\xbd\x29\xed\xd6\x5e\x70\x5c\x40\x3c\x8a\x28\x78\x65\xc5\x7c\xb4\xba\xae\x54\xde\xd1\xd0\xc8\x37\x1f\x92\x3e\x82\x57\x30\xeb\xd9\x52\x1a\xe7\x1f\xaf\xc5\x52\xdd\xf7\xb1\x66\x03\x5b\x5e\x38\x6a\xb9\x98\xff\x5e\xd6\xc4\x31\x27\x68\xfc\xc1\x89\x14\x2c\xf9\x7f\x37\xa2\x96\xe4\xcb\x83\x7c\x85\xc0\xb1\xc0\xaa\xa6\x52\x94\x8c\x21\x55\x39\x65\x2f\xf2\x9c\x71\xf6\x60\x15\xd5\x84\x65\x0b\x91\xdd\x31\x39\xf7\x2c\x90\xda\xdd\xbe\x4c\xfd\xfd\x37\x98\xd1\x74\xf0\x9c\x00\x97\xed\x41\x04\x7e\x80\x6c\x15\xb9\x14\xda\xf0\x25\x64\x03\xa8\x19\xe4\x0f\xe4\x28\x0d\x30\x4a\xbc\xec\xbc\x8a\xf1\x10\xac\xe5\x79\x2f\x4a\xe3\x64\xd0\xcb\x9d\xdf\x4e\xfc\x44\x62\xf1\x6c\xc3\xc4\x18\x7b\xab\x66\x0e\x21\x0e\x28\xbe\xe3\x64\x61\x70\x61\x3e\x8d\x45\x19\xed\xc2\x94\xd2\x91\x2d\x78\x79\x8b\xbf\xdc\xf3\xa2\xf1\xab\xeb\x07\x18\x15\x80\xae\x19\xb9\x14\x0f\xf4\x99\x7b\x8c\xe2\xd6\x33\xf6\xd6\x8c\x60\x6c\x26\x16\xfc\x5e\xaa\x5a\x7f\xfb\x07\xc6\xce\x2d\xc6\x17\x76\xd1\x5f\xc0\x18\x17\x99\xdb\x4e\x3b\x4f\x60\xdf\xed\x61\xa4\x15\x46\x99\x09\x26\xca\x7b\x59\xab\x72\x29\x4a\xc3\xee\x79\x2d\xad\x11\x35\x46\x2f\x93\xb1\xdc\xff\x3d\x50\x80\x46\xe8\x71\xc7\x6d\xa3\x98\x29\xe9\xc6\x52\xda\xca\xb0\xc0\xeb\xcf\x92\xc1\xa9\xf0\xcf\x5f\x7c\xf3\xf5\x94\xbd\x60\x37\x34\x99\x8c\x17\x05\x78\xe7\x15\x0d\x8e\x3e\x95\xa0\x47\x1c\x67\xd6\x42\xfd\xd3\x37\x5f\x7f\xc5\x0c\xaf\x6f\x05\x9c\x38\xf1\xb7\xcb\x3f\x5d\x42\x6c\x1a\xa7\xa8\xb3\x87\xb6\x8a\x72\x09\x53\x45\xa3\x29\x0f\xb4\x4c\xd7\x24\x1c\x63\xec\x2f\x01\xbd\x98\x7a\x00\x37\x50\x30\x58\xb4\x74\xea\x90\xda\x8d\x8a\x1a\xc4\xfe\x41\xe6\x50\x3a\xc4\x30\x4c\xdd\x58\xab\x4e\xb3\xef\xdf\xbe\xbd\x79\xf5\xee\x9f\xaf\xaf\x5e\x7d\x70\xff\xfb\xf7\xb7\x37\xef\x27\x7d\x0f\xae\xdf\xbe\x4b\x1f\xc0\x0f\x18\x1f\x9e\xfe\xf8\xc1\xd2\xed\xc3\xfb\xab\xeb\xfe\x6f\xa2\xc7\xef\xde\xbe\x7f\x3b\xfc\xdc\x5b\x70\x83\x00\x5e\xbc\x7c\xf9\x8e\xfc\x67\xb5\x5d\xbc\x55\x53\x84\x5d\x02\xd3\xe2\x70\x25\x1e\x64\x07\xe4\x5a\xcb\xdb\x92\xee\x04\x64\x35\x62\x6d\x58\x8b\x8a\xc3\xeb\xec\xf5\xf5\x5e\xea\x0f\x37\x39\xba\x27\x8e\x8d\xb4\x24\x3d\x23\x8a\x87\xd7\x8c\x63\x66\x1a\x50\xf1\xf5\x35\xe3\x79\x5e\xf7\xb8\x45\x76\x21\x84\xdd\xcd\x4d\x08\xd8\x41\xef\xb7\xdd\xe7\x94\x5d\x4b\x0f\x62\xa6\x55\x76\x27\x86\x7c\xfd\x31\x81\x9c\x57\x67\x24\x44\x34\x89\xf6\x35\x22\xa6\xec\x67\x07\x30\x49\x27\x54\x96\xa6\xb5\x14\x76\xe9\x7c\x14\x99\xc7\x26\xba\x54\x0a\x4b\xb0\xb2\x3c\x71\xf9\x2c\xee\xbb\x1c\xdd\x21\x01\x7c\x3b\xd1\xc5\x07\xf5\xda\x01\x92\x10\x30\x1c\x64\x0b\xa7\xd5\x1a\x4b\x4d\xdd\x52\xe4\x4f\x42\xb8\xf1\xbc\x80\xc9\xc0\xc1\xc2\x43\x4a\x83\x7f\x2c\x57\xf0\x16\xd0\x0f\x70\x0a\xae\xc0\x7d\xd2\x3c\xbe\x00\x3c\x08\x53\xe2\xf4\x9d\x43\xb1\x81\x15\xf2\x5e\x94\x42\x6b\xab\x86\x66\x62\x42\xb6\x27\xa4\xa8\x8a\x32\x87\xe0\x2b\xbc\x58\x68\xea\x41\x2b\xaa\x56\xb3\xc4\xd3\xe9\x38\xf5\x7f\x4a\x65\xfe\x4f\x2b\x5a\x1b\xad\xa3\x8b\x85\xe0\x85\x59\xfc\x2f\xba\xdb\xec\x60\x29\x1e\x07\x32\xc0\x5b\x40\x55\x99\x4e\x8c\x9d\x5d\x9c\xd9\x13\x2e\xbe\x84\x89\x24\xee\x45\xe0\x93\x7f\x11\xb2\x77\xe1\x9c\xc9\x65\x41\xf9\x0b\x2d\xe0\xde\x03\xec\xa2\x3a\x4a\xef\xa7\x4b\x62\xb6\x9d\x56\xb4\x87\x62\xf6\xbf\xa2\x56\xe3\x35\x9d\x27\xf0\x07\x18\x72\x3c\x3b\x0b\x95\x91\x7f\x6c\xc2\x4a\xe5\xf0\x39\x1c\x3b\x41\x0d\x7d\x96\x51\xae\xc0\x85\x59\x56\xc4\xe0\xcf\xf6\xe5\xeb\x08\xae\xc2\xbe\xda\x68\xa1\xd9\x99\x80\xaa\x03\xd1\x3d\x7b\x40\x49\x78\x9c\x28\x69\xef\x87\x14\x8a\xf7\x83\x22\xfb\x14\x9d\xa7\xe8\x13\x17\xee\x14\x28\xc7\x88\x9b\x2e\x25\x02\xf9\x79\x79\x02\x66\x9a\xac\x62\xa8\x21\x8e\xc3\x4c\x93\x55\xdf\x5a\xeb\x91\xbc\x3d\x27\x59\x96\x61\x4e\x64\xb8\x5a\x83\x11\x2b\x07\x60\x52\xbe\x0b\x90\xf3\xb6\x2d\x2e\x49\x32\x2e\x70\x55\xd7\xb5\xaa\x35\x55\x35\x79\x76\x49\x4e\x3a\x3d\xf1\x61\xf9\x34\x00\x7d\x68\xf9\x85\x50\x2b\x51\xee\x27\x0e\x89\x28\xd0\x8a\xef\x17\x87\x67\x7f\x3a\xbc\x3c\xb4\x74\xf5\x8e\xf2\xb0\x4e\x4b\xa7\x1a\x3a\xd2\x93\xa7\xd1\xd2\x0e\x0d\x90\x8a\xb0\x63\xb8\x72\x0d\xe4\x75\xf2\xc8\xc6\x82\xc1\x23\xd1\xe8\x48\x06\x5d\x2d\x38\x2d\x4d\xa8\xf9\xa4\x1c\xb8\x96\x20\x65\xad\x9b\xc2\xd8\x03\x93\x47\x15\xc5\x81\xf6\xc5\xe0\x2f\x23\xb1\x79\x70\xde\xe7\x3b\x09\xe7\x3b\x74\x2d\x39\xea\xca\x32\xab\x85\x3d\xed\x58\x46\xa4\x22\x64\x14\x7b\x76\xe2\xfd\xe0\x80\xf2\xe2\xb7\x81\x64\x0b\x38\x84\x1e\xe9\x7a\x58\x06\x37\x81\xa8\xf8\x8a\x93\x90\xf5\x1b\x81\xe5\x5d\x88\x10\x40\x4f\x16\xde\x21\xc2\x2d\x56\xf2\x45\x4b\x84\xa8\xda\x41\x2d\x6f\x6f\x45\x0d\x84\x6d\x61\xa5\xc8\x60\xe8\x91\x8f\xcd\xb2\xd1\x63\x3b\x9c\x48\x3e\x5a\x2a\x65\xd9\x14\x46\x56\x85\xe7\xb8\x66\x7f\xd4\x85\x7a\xf8\x7c\x5b\x99\xc1\x30\x36\x55\x2a\xa3\x4a\x99\x71\x7b\x12\x84\xf9\x72\x1d\xad\x84\x68\x6f\xfd\x5d\xbd\x1c\x43\xbd\x00\xb4\x16\x51\x96\x8d\x36\x3e\xd8\x97\xf1\x5b\xbb\x79\xe1\x7c\x1c\x00\x45\x73\x49\x89\x33\x57\x75\xa0\x8c\x28\x2d\x41\xf3\xe8\x1a\x80\x24\xd8\xd2\x4a\x33\x5e\xae\xa5\x96\x3f\xbe\xc1\x78\x53\x9f\xe5\x8a\x89\x8e\x38\x75\x3f\x35\x74\x14\xdf\x8b\x7a\x05\xd7\x07\xb4\x3a\x03\xd5\xf4\x84\x2d\x05\x87\xe8\xda\xa6\x32\x8a\x7d\xe5\xe6\x71\xd0\xc5\x53\x0b\x9e\xcb\x78\xf5\x80\xbc\xc9\x52\x1a\xc9\x0b\xab\x49\xf8\x6a\xf4\x12\xf1\xb1\x21\x11\xc0\x38\x22\x79\x86\xf7\x95\x2b\xaa\x46\x44\xb1\x57\xd1\x48\x98\x17\x0f\x01\xe2\x8e\x67\x7b\x69\x59\xac\x26\x04\x01\x9f\x73\x79\xdb\xd4\x41\xcd\xa7\xc3\x46\x17\x3f\x1e\xfd\x60\x22\x4c\xd9\x15\x30\xc5\x39\x16\x6f\xb0\xa2\x9b\x65\x9a\xd5\xca\x6a\x59\xf1\xda\x47\xf2\x24\x80\x53\xa9\x77\xb9\x3f\x48\x03\x0c\x9f\x09\xe5\xeb\xa2\x22\x50\x31\x84\xa3\xf2\x7a\xdb\x33\x71\x2f\x83\x81\xc8\x18\x60\xef\x78\x2d\x9c\xcf\xc2\xcf\xf6\xc0\x8c\x25\x2e\xae\x41\x25\x53\xa5\x06\x27\xb3\x89\x92\xf5\x29\x23\x3a\xd5\xb0\x93\x1e\xb7\x71\x94\xe0\xcc\xf3\xd5\x24\xfa\x9b\x72\x81\x22\x75\x15\x29\x7b\x77\xeb\x70\xd0\x23\xf1\x8d\x0b\x40\xbb\xc2\x00\xb4\x89\x45\xe2\x85\xfe\x49\x8b\xfa\xbb\xaf\xbf\xfa\xea\x8b\x2f\x07\xd8\xd7\xfe\x8e\xca\x73\xb8\x98\xae\x4e\x68\xb7\x87\x9a\x1c\x02\x9a\x76\x91\x03\x78\xb7\x91\x39\x83\xb1\xf7\x0a\xa0\x3a\xbb\x8a\x93\x05\x92\x0d\x2f\x20\xa3\xe0\x65\x36\x5b\xb1\x8a\x6b\xd8\x64\xc3\xe0\x2e\x4b\xa7\x29\x19\xd7\xac\x29\xab\x5a\xde\xcb\x42\xe4\xb7\x02\xb2\x02\xeb\xf4\xba\x52\x96\xec\x06\xcb\x07\x89\x9c\x55\x0b\xb8\xc7\x4f\x8b\x28\xb8\x20\x1e\x77\x83\x41\x81\x3c\x5c\x0f\xc6\xf2\x74\x62\xe6\xbc\x80\x68\xf6\xd3\xeb\x97\xec\x82\xfd\xed\xf5\xcb\x6d\x4a\x28\xb8\x70\xc3\x0f\x14\x6e\xb8\x59\x1a\x68\xd2\xb7\x22\xc7\xf0\xaa\xe9\xae\xf2\xe0\xe3\x39\x03\xc4\xf5\xa2\x10\xd3\xfc\xd6\xa5\x78\x60\x88\xd7\x7e\x62\xe1\x96\x7a\xb7\xf0\x47\x99\x8e\xb8\x54\xb9\xb0\xa2\xa1\x85\xa1\x6b\xa3\xfc\xec\x4c\xfb\xa9\xd2\x4c\x71\xd1\x87\xaf\x48\xa4\xb8\x46\x64\x77\x90\x12\x2a\xac\x90\x84\x7b\xf5\x48\x89\x04\x79\xd0\x8c\xe3\x93\x73\x52\xf2\xde\xdd\x7d\x5c\xc1\xa8\x5b\xf1\xa9\x18\x2d\x7a\x28\x21\xe9\x87\x8e\x71\x14\xa1\xc4\x46\x8f\xee\x78\xa8\xa5\x81\x3b\xb6\x5a\x29\x33\xa7\x1c\xba\x75\xb8\xee\x74\x11\x91\xaa\x96\xb0\xff\x93\x20\xad\x99\x82\x8f\xd2\xc4\xcb\xe7\x9f\xd3\x38\xdc\x10\xfc\x50\x14\xea\x81\x0c\xd7\x41\xf9\xc1\x10\xef\x63\x32\x19\xd0\xf0\xb2\xfd\x4a\x67\xbc\x00\x3c\xb7\x64\xf3\x43\xc2\xe6\x76\x1c\xeb\x8b\x81\x41\x62\x6e\x5b\x25\x88\x71\x43\x7e\x7d\x32\xe1\xdf\x1c\xad\x1b\x46\x5c\x53\xdb\x6d\x03\xd8\xe9\x22\x4c\x86\x68\x10\xc5\xdb\x7a\x3d\x0d\xef\x86\xb8\x8f\x3e\x54\x3d\xaf\xa7\xec\x45\x9a\xcf\xd6\xb1\x23\xd7\x12\xdf\xdf\xa9\x72\x76\x6b\x8f\x2a\xb0\x71\xfd\xf1\xd9\xe5\xe5\xe5\xe7\xec\x61\x21\xb3\x85\xcb\x2c\xba\x1c\xaa\x26\x54\x37\xe5\x24\x29\x79\x85\xce\x3e\x4c\xbc\x19\xbc\xef\xa2\xe7\x58\x70\x25\x35\xe0\x6a\x4e\xa2\xef\x11\xc2\xad\x6e\x2a\xa6\xf6\x8f\xef\x2c\x72\x43\x9b\xe2\x88\xc8\x56\x47\x65\x8a\x5a\x1c\xde\x11\x27\x4c\xd5\xbd\xc4\x3f\xa4\x46\x7c\xd5\x17\x25\x31\xb1\x74\xe2\xa5\x96\x83\xd9\x24\xff\xa4\x57\xd9\x2b\xf7\x62\x1a\x16\x67\x0d\x7e\xa5\x31\x89\xed\xde\x02\xd6\x90\x5d\xc6\x4a\x81\x72\xe5\x7f\xdd\xdf\xc2\xed\x8d\xf3\x98\xf6\x4f\x8c\xe5\x62\x2e\xcb\x24\xfa\xaa\xaa\xc5\xbd\x54\x8d\x2e\x56\xee\xe1\x40\xe4\x08\x88\x12\xd0\x05\x14\xe4\x8e\xb7\xf9\x9e\xb0\x23\x19\xe1\xcb\x28\x50\x09\x85\xbd\x39\xa3\x9b\x99\x36\xd2\x34\xa0\xc3\x10\x7b\xcc\xed\xe9\x2c\x21\x28\x04\x71\x24\xfe\xb4\x2a\xe5\xb5\x67\xa9\xd3\xf0\xb8\x65\x54\x84\xaf\xfb\x6e\x14\x46\xb7\x9e\x85\xa1\x2e\xcf\xa3\xb1\xf1\x74\xdc\x73\x23\x9e\x96\x81\xa1\x02\xf3\x10\xdb\xc6\x32\xab\xc5\x28\xe7\x69\x38\x28\xb3\xfe\xa9\x8a\x66\x29\x6e\x9a\x59\xc5\xcd\xe2\x55\x79\xef\x89\x3e\xb1\x84\x86\xda\x7c\x47\x63\xd8\x3d\x8c\x4d\x9b\x00\x8e\xf5\x8b\x96\xb7\xe7\xda\xa8\x9a\xdf\x6e\x64\xd3\x8f\xfc\x4e\x30\xf0\x7b\xf1\x24\x5e\xc0\xc1\xca\x78\x89\xa9\x9e\x86\x28\xce\xcb\x30\x17\xa6\xe6\xc3\xc1\x58\x1d\x4b\xec\x38\x84\x45\xdb\x60\xa6\x55\x01\x45\xc4\x87\xeb\x3a\x0e\x53\x18\x7c\x98\xdb\x10\xb8\x3b\x66\x4a\xf3\x5f\x6e\x0a\xf5\x70\x08\xca\x93\x23\x6f\x90\xfa\x6e\x0f\xec\x11\x7b\x2c\x01\x90\xe0\x28\x35\xd8\x09\x45\x4f\xe5\xb0\x63\x32\x67\xc6\xb3\x3b\x23\xb3\xbb\xa1\x58\x9d\x43\x33\xc6\x8f\xf7\x44\x99\x12\xf0\x83\x6a\x2b\xa7\xe5\x08\xd6\x6f\xb4\xc7\xac\xed\xd9\x41\xf5\xa0\x2d\xf5\x2d\x04\x3b\x75\x02\x0b\x1c\x49\x83\x97\xb6\xa7\xfd\x67\xff\x74\x55\x0b\xa1\xbc\x69\x47\x73\x3a\x5d\x04\xe5\x9c\x7c\x52\xa7\x4b\xe2\x32\xca\x23\x83\x67\xc9\x67\xd3\xff\x31\x10\x28\xe8\x7e\x17\x1f\xab\x9a\xd1\x7d\x54\xec\xee\x70\x36\xf3\xf3\xe9\xff\x18\x20\xcf\x5c\xd5\x2c\xf9\x32\x10\x8c\xb1\x2f\xa6\xff\x63\xa2\x2c\x96\x44\x17\x82\x6f\x39\x1a\x4c\xea\xf2\xcc\x40\xe5\x7e\x59\x53\x6c\x2e\x0a\x2d\xcb\x0a\xc1\xcb\xa6\xea\x64\x9e\x1c\x87\xe9\xe8\x16\xc6\x02\xd4\x98\xf2\x0d\x67\xe5\xad\x05\xe0\x3e\x61\x90\xab\xff\xdc\xb7\xc5\x31\xc7\xac\xa5\xca\xd1\xd3\x9e\x87\x23\x64\xe8\x4b\x90\x06\xbd\xed\x20\x33\xff\x1c\x87\xd1\x1a\x6c\xe8\xb6\xb9\x1f\xa3\x43\x2c\x4a\x6b\xff\x40\x9a\x83\x9e\x38\x02\xc2\x9f\xc8\x8f\x1b\x4c\xc8\xa6\xba\xbe\x94\xe2\x38\xc0\x18\x20\x4f\xa9\x72\xf1\x2b\x7b\x05\x00\xe3\xb4\x14\x0b\x71\xb6\x72\x79\xb8\x3a\x14\x5c\x72\x03\xa0\x2d\x3e\x53\x8d\x61\x15\x44\x47\x46\xa9\xe0\x65\xee\x57\xc1\x16\x66\xdd\x84\x2d\xbd\xba\xf4\xfd\x21\xec\x74\x89\xda\x94\xa2\x12\x25\xcf\xc2\xc4\x29\xfd\xa7\x95\xd9\x71\x27\xcb\xfc\x3b\xfb\xb1\x47\x5c\x35\x75\x26\xa0\xce\xef\x42\x04\x3a\x51\x86\x19\xad\x36\x24\x6c\x30\xc8\x67\x22\xa9\x4e\xd4\x1e\x3a\x1d\x76\xfd\x90\x00\xd4\xe7\x9c\x76\x07\x1d\x18\xf0\xaf\xca\x2c\xfa\xb9\x1a\xee\xa5\xb4\x28\x9d\x4c\x74\xd3\xf2\x23\x5e\x60\x84\xf4\x66\xfb\xd4\xca\xc4\x05\xc2\xeb\x93\xbe\x57\xf7\x92\x5a\x97\xbc\x57\x85\x73\xad\x15\x72\x29\x07\xc3\x67\x23\x49\x7b\xa3\x5e\x61\x11\x90\xf7\x5c\x96\x94\x02\x5e\xb3\x1f\xdd\x0d\x3f\x04\xda\xfe\x72\x23\x6a\xc9\x8b\x5f\x99\xb0\x23\xd1\x6d\x9e\x7d\x00\xfb\xf1\x52\x96\x61\x5c\x97\xd9\xf6\xcb\x4b\xa9\xeb\xa6\x32\xf2\x7e\x73\xc1\x5f\xbb\xd9\x43\x48\xc1\x39\x09\xae\x28\x79\x2d\x15\x25\xa6\xb4\x41\x4f\x5c\xc2\x4b\xe0\x10\xa0\x45\xa7\x75\xae\x59\x45\xd7\x80\xe1\x53\xbc\x60\x04\x92\x74\x96\xfc\xd7\x03\xf4\xb6\x1a\xa2\x4b\x6f\xa0\xd2\x24\x21\x3b\xdc\x76\xda\x9f\x31\x5b\x8c\x17\xbb\x12\xfd\x46\x96\xb7\x48\xf2\x40\x71\x00\xe9\xcf\x4a\x30\x4a\x66\xc9\x58\x68\x9c\xb5\x1d\x7f\x0b\x5a\x27\x29\xdb\x2d\xfa\x58\xcd\xe1\xb4\x49\x8e\x05\xac\x60\x40\x91\x33\x7b\x36\xf4\x21\x70\xee\x32\x92\xa8\xee\x52\xcc\x10\x39\xa8\xd6\x83\x39\x73\xae\x4d\x4e\x8b\x0b\xa2\xcc\xbb\x67\x87\xed\x98\x80\xe1\xe2\xff\x78\x7b\xb3\x99\xd2\x20\xbf\xaf\x3e\x1a\x51\xe6\x22\x67\x69\xfc\xf8\x8d\x30\x16\x08\xbb\x2a\xb8\x4e\x6a\x44\x91\xf5\xa7\x4a\x7c\x0f\xa5\xdc\x55\x5b\xaa\x05\xa9\x11\xd7\xb1\x87\x92\x75\xed\x72\x03\xb5\xb3\x14\x4b\x55\x53\x4e\x43\xd5\x6c\x7d\x8c\xbe\xba\xfe\x09\x73\x67\x11\x0c\x8d\x12\x0d\xd2\x49\xa9\xc0\x18\x15\x7e\x2f\xec\x6c\x68\x32\x58\xa5\xe0\x5a\xe5\xff\x78\x7b\xf3\xb7\x86\xd7\xbc\x34\x62\x54\x41\x61\x20\xfb\xe6\xac\x2d\xbf\x85\x5e\x38\x7a\xe8\x1e\x16\xf9\x9e\x4f\xc3\x8d\xa6\x62\x5e\xd5\xe2\xc6\xbe\xed\x12\xb4\x78\x51\x78\x08\xa0\x46\xef\x64\x51\x84\x9b\x93\x2d\x13\xb0\xaa\xf8\xaa\x5b\x9b\x38\xe8\x1b\xcc\xbf\x33\xdc\xe3\x30\x85\x4e\xd3\x6d\xc3\x3b\x91\x09\x79\x4f\xaa\x65\x2e\x45\x11\xef\x76\xd1\xe5\x79\xab\x15\x15\x82\x82\xde\x80\xbe\x2a\x89\x2b\x3c\x46\xa3\xaa\x90\x30\x19\x72\xb9\xa6\x89\xc1\x93\x24\xe8\x85\x11\x94\xba\x8b\x73\x39\xa3\xf4\x69\x7f\x21\xef\x53\xfa\x92\xaf\xa6\xec\xaf\xa1\x73\x15\xdd\xdb\xfb\xdc\xcf\x4e\x33\xad\x38\x69\x9e\xd2\xd2\x1e\xa8\x27\x05\xf9\xed\xfb\xb1\x0d\x40\x5d\xd5\x33\xcb\x47\x70\xa1\x25\xc2\x00\x97\xc2\x60\x30\x49\xac\x01\x01\xd1\x3a\xce\x86\x24\xf1\xae\x89\xfe\x2e\xa2\x24\x22\xd5\x58\x51\xae\xc5\x07\x3b\x6c\x5b\x87\xbc\xc8\x97\x52\x83\xed\xf8\x20\x66\x16\xa5\x09\x66\xb2\x2f\x1b\x83\xf7\x36\xf4\x73\x7b\x0b\xb5\xe2\xca\x2b\x79\xbe\xe4\x56\x1d\x88\x7a\xf5\x6b\x00\xf5\x33\x7e\xc2\x7e\x09\xf7\xa3\xdf\x5e\x61\x3a\x9d\x7d\xa7\xfc\x15\x86\x70\xda\xbc\x33\x92\x13\x7c\xa8\x33\x32\x4a\xb8\x9f\x5d\x76\xa0\x78\xfe\x80\xca\xd5\x70\xa9\xe5\xa4\x94\x92\x4f\x5f\x18\x23\x96\x95\x71\x55\x70\x60\xda\x96\xb8\xfd\x10\x82\xe6\xf3\x19\xa1\x7f\x01\xa0\x70\xc3\xe2\xe2\x0c\xf0\x53\x57\x85\x24\xfe\xdc\x6d\xd2\x96\xfd\x90\x0c\x4c\xc3\x43\xbc\x8f\xab\x86\x40\x95\x2c\xfe\x82\xe9\xc1\xf0\xef\x44\x00\x61\x96\x50\x19\x3f\x7c\x8c\xfb\xcc\x76\x98\x87\x9a\x2e\x28\xa3\x51\x89\x04\x24\x54\x3f\x20\x37\x07\x57\xa2\xab\x3b\x07\xba\x9f\x1a\x9c\x07\xd5\xa8\x76\xf3\x18\xb1\xff\xf1\x4a\x7a\x19\xbb\x20\xbc\xc6\x0a\x31\xb5\x76\x3b\x89\x18\xf7\x8c\xb5\x93\x20\x77\xe1\xfc\x06\x44\x99\x7e\x8d\x45\x39\x17\xa5\x3c\x94\x24\x77\xa5\x18\xe5\x70\x1f\x49\xee\x9f\x42\x38\x82\x91\x24\xd3\x34\x8e\x27\xc8\x54\x42\xa6\xad\xdf\x0e\x2a\xc7\x15\x91\xf5\x02\x06\x0b\x4d\x21\x3b\x4a\x75\xbc\x40\xbf\x13\xb7\x12\xf2\xa7\x23\x28\xbc\x3d\xbb\x94\x2b\x49\x26\x7f\x2c\x7e\x46\xe1\x35\x7b\x55\x15\x2b\x67\x47\x10\x93\x42\x0c\x05\x56\xdd\xde\xc0\xc4\x18\xaa\xe7\x22\x2a\xa3\x48\x55\xc5\x35\x75\x1c\xa6\x46\xad\x1f\x1f\x29\x86\x01\xc2\x5b\x60\x42\x37\xee\x1d\x0c\x8e\x2e\x4f\x5d\x35\x73\x12\x89\xea\xd1\x6e\x3b\xc9\x54\x04\xe7\x89\x4a\x55\x2e\xca\x55\x04\x73\x17\x99\x42\x79\x0a\x21\x1f\x5b\xc9\x54\x7b\xfc\xe3\x49\x14\x8c\xc4\x8d\xe1\x59\xfb\x4e\x6a\x3f\x19\x4a\x4f\xa2\xdc\x17\x29\xf5\xa3\x51\x74\xde\x68\xa9\x29\x37\xc9\x0a\x5a\xf0\xa0\xd2\x21\x30\xa7\xb4\xbb\x89\x73\x3a\x28\x3c\x6f\x9d\x69\x1a\x9d\xe9\x66\x76\xee\x4e\x7d\x7e\x03\x81\x83\x0e\xbd\x10\x36\x99\x23\xef\x11\x40\x13\x6a\xe4\xe5\xcf\xe5\x51\x89\xad\xde\xa2\xb2\x47\x63\x4e\x2f\x22\xe0\x97\x8b\xca\xa1\xf9\xda\x3a\x47\x62\x5e\x6b\x4c\xbf\x88\xfc\xb8\x6a\xde\x46\x54\xa7\x4c\x44\xfa\x75\x91\x16\xf4\x9d\x4b\x43\xc2\x6f\x4f\xcd\x6c\x67\x8d\x9c\x84\xa3\x15\x39\x8f\x91\xde\x4b\x5e\x79\xfa\x1e\x9a\x7d\xf6\x25\xa3\xbb\x03\x52\x27\xe9\x0e\x7b\xa0\xf3\x58\xa6\x96\x55\x21\x79\x49\x1e\xff\xe4\x43\x0d\x61\x61\xc8\x43\xac\xa1\xc3\xfc\xeb\xc1\x81\x9b\x7e\x42\xf5\xc8\x52\xd0\x2d\xfe\xb2\x17\x65\x9f\x42\x76\x20\xc9\x89\xc2\x21\xf5\x8e\xc7\x1a\x7f\xc1\xcb\xdb\x76\x7e\x53\xf4\x02\x39\x20\x21\x19\x68\xe2\x9b\xcc\xb8\xda\x46\x9e\xec\xe3\xb0\x69\x4d\xc1\xcf\x90\xb2\x64\xec\xb8\x0b\x69\x04\x54\xce\xc9\x99\x15\x23\x5d\xf1\x4c\xb0\x19\xd7\xc1\xd7\xe0\x50\x0b\x8f\x3b\xd5\x98\x28\x6e\xf5\xd4\x1a\x0e\x02\x62\xa4\xe9\x46\x9b\x1c\x6c\x21\xd0\x5a\xcb\xb7\x97\xf7\xc0\xd1\x58\x2b\x0d\x4e\xc0\x5b\x09\xad\x93\x9c\xe7\xe4\xf0\xa7\xc9\x09\xcb\xb9\x49\x4f\xa6\x8d\x16\xaa\x54\xb5\x13\xdb\x63\xb1\x21\x19\x64\x03\x0b\x7e\xc2\x58\x85\x94\xfe\x0f\xdc\x6a\x95\xaf\x7c\x52\x1d\xf9\xe4\x41\xdb\x80\x11\x89\x66\x14\x44\x9e\x91\x5b\xcf\xaf\x3b\x07\xc8\xf5\x2a\x98\x51\xef\x4d\x68\x34\x40\x38\x69\xdf\xb7\xa4\x81\x42\x46\xd0\xf6\x83\xe2\xae\xa2\xa3\x25\x1e\xa6\xa3\x4c\x84\xb9\xbc\x65\x56\x9d\x62\xe0\x18\xcf\x92\x01\xa6\xec\x9d\x73\xad\x63\xb1\x40\x9a\x3f\x5d\x34\x04\x07\xa4\x2b\xe5\x92\x68\x10\xa9\x59\x21\xb4\xb6\xf3\x2f\xa3\x99\xf7\xe0\x29\x35\x65\xe3\xfa\xe1\x7c\xda\xa3\x35\x90\x5b\xc3\x76\x3f\x96\xb7\xa5\xaa\x45\x1b\x5b\x6b\x03\x47\x9f\x6e\xc6\x36\xca\x79\xfc\xe3\xb2\xc9\x16\xac\x50\xe5\x2d\xf6\xda\x4c\x15\x91\x65\x26\xcb\x69\xdb\xf8\xfc\x98\x4a\x47\xea\x4c\xdd\x8b\x7a\xc5\x72\x95\x35\x14\xfa\x75\x14\x01\x97\x65\x56\x34\x79\x98\x62\x30\x2b\x64\xd9\x83\x86\x1e\x71\xbd\xe5\xb7\xdb\x1a\x74\x12\x1d\x86\xf0\xba\x01\x8a\xee\xde\xd6\xaa\xa9\x5c\xd8\xa0\xd4\xa1\x57\x9b\x25\x17\x5e\x6e\x76\x47\x9e\x6e\x84\x7d\x71\xff\x2c\x80\xbf\xb8\x17\xb5\x76\xfb\x15\x06\x0c\x75\x87\x1a\x1c\xc6\x39\x0e\x88\x2a\x2d\x17\x8e\xdb\x1b\xc3\x51\xb0\xff\xbd\x96\x89\x06\x08\x24\xe3\x5f\x6c\x98\xce\x10\x29\x8e\x27\x78\xaa\xce\x45\x2d\x72\x22\xc0\xf1\xb6\x37\xf2\x3b\x04\xb3\x6e\x7b\x9f\x4e\xbf\x2d\x87\x17\x2f\x0f\x2a\xb8\x42\x83\x75\x17\x79\x14\xc9\x3e\x2b\x5d\xaf\x9f\xdc\x2a\x28\x96\x73\xc3\xd9\x9d\x58\xa5\x8a\xce\xa2\xc7\x0b\x0c\xf1\x59\x40\xa7\x66\x9f\xf9\x74\x27\x56\x93\x70\x4a\x2e\x95\x59\x50\x8b\x5e\x07\x31\x02\x66\xff\xc9\xf3\x3c\x94\xdb\x9e\xcb\x5a\x1b\x3f\x0d\xa9\xbd\x57\x33\xb6\x38\xd3\xad\xd8\xeb\xed\xbf\x60\x2d\xe2\x3b\xb1\x8a\xc2\x24\x00\xb8\x3b\xd1\xfb\x57\x8f\x28\x2d\x8e\x8b\xa9\x85\x70\x6c\x99\x69\xd9\x23\xbb\xd9\x45\x08\x4c\x77\xed\x9b\xa1\xab\x85\xf6\xb0\x89\x87\xb6\xf5\xcc\x71\xe4\xf8\x97\x0d\x03\x34\x41\xd7\xb4\x9c\xcf\x45\x0d\x41\x39\x46\xd9\x45\x4d\x2a\xf1\xc4\xfc\x59\x8b\xcb\x9e\xdc\x6b\x9f\xa3\x99\xb7\x67\xb1\x31\x38\x1c\xbe\x70\x3d\x45\xa0\xd6\x18\xc3\x18\x6f\x7a\xff\x0c\x4a\xbf\x26\x98\x46\xd7\xce\x3d\xa7\xf0\xd8\xc9\xb6\x06\x3c\xf5\x2f\xbf\x7f\x6e\xe1\xe3\x2d\x6b\x32\x46\x7b\xe5\x57\x83\x40\xe9\x16\xa6\x14\x0f\x78\x2b\x0e\xf3\x05\xbb\x0f\x45\xb2\xf2\xd5\x81\xfd\xb9\x1a\xc3\x60\xd3\xc6\xef\x8f\x23\x99\x55\xdd\x94\xe8\xdd\x3a\xb9\x20\xd2\xd0\x63\xe5\xae\x7b\x45\x1c\xb4\x3b\xd0\x1d\x3d\x02\x38\x12\x99\xf2\x53\xff\x39\xb9\x9e\xd7\x08\x04\xb1\x51\x67\x0b\xb1\xe4\x54\xe1\x01\x2d\x32\x1d\x9a\xe7\x50\x54\x9c\xdd\x9d\xb0\xc8\x88\xd5\xfa\xc9\x56\xe2\xb0\x4b\x94\x57\x67\xe0\xbf\xd0\xb6\x03\x68\xd3\x30\xce\x0a\xf4\xa1\x8c\x4b\xde\xbe\x65\x43\xcb\x1d\x84\xcc\x5a\xe5\xee\xc3\xbe\x8f\xf0\x6a\x8a\x52\x40\xfc\x66\x76\x4c\x09\xf3\x44\xa4\xf6\x5b\xc7\x17\x2b\xe7\x21\x42\x07\xba\x6f\xd0\x8b\xc5\x2f\x3c\x4e\xbb\xdb\x33\x91\xf9\x50\xb6\x3a\x24\x5a\x8d\xa0\x72\x3d\x7c\x56\xaf\x54\x8e\x4c\x4e\xbf\x6b\x59\x08\x0b\xc1\xde\x53\xf9\x77\xa9\x4a\xaa\x7a\x79\x1d\xfa\x0c\x86\x23\x3c\xcc\xed\xa8\x1b\x58\xf0\xcd\x65\xaa\x34\xb5\x2a\x42\x5e\x2b\x3a\x82\x7a\xcd\x3c\xcc\x1c\xc5\xe5\x76\x2c\x76\x53\x16\x82\x73\x47\x12\xf7\x21\xd3\x13\x43\x5d\x63\x87\x6e\xbf\x31\x4a\x18\x8e\x15\x86\x54\xc7\xd0\x80\xe8\xfd\x2d\x57\x9b\x87\x8b\x89\xd2\x7f\xad\xec\xfd\xc8\x7c\x2d\xc2\x64\x5c\xfa\xdb\xa0\x56\xf8\x6f\x94\x2a\x3e\x78\x61\xbe\x26\xf4\x22\x55\x58\xc7\x93\x2c\xc8\x6d\xc9\x0a\xa5\x45\xbb\xfd\xe8\xc1\x44\xa4\x29\x33\x55\xe6\xa0\xc9\xa1\x76\x56\x2d\x60\xd2\x81\x70\x56\x80\x23\x3c\x3c\xad\xb6\xb6\x7a\x68\x9f\x88\x61\xb9\x16\xaf\x65\xee\x1b\x90\x5f\xbd\x60\xb3\xa6\xcc\xa9\xa9\x9d\x56\xb4\xa1\x18\x6a\xd2\x63\x99\x80\x81\x64\x41\x3c\x22\x5c\xe1\x65\xca\xa5\xc0\x4c\xf4\x36\x51\x43\x70\xc3\x71\xbc\x7c\xfc\xf6\xb6\x16\xb7\xdc\xa8\xfa\x9c\xf2\xad\xf5\xb9\x59\x88\x73\xcd\x97\x55\x21\x2c\xcf\x30\xfc\x6c\x04\x3f\x3d\x24\x76\xd3\x69\xaf\xef\x72\xb9\xed\x1c\x9f\x4d\x9f\x7d\xc3\x6e\x00\x3e\x1a\x5f\xd7\xaf\xa1\x16\xbc\xa8\xa3\x04\x48\xec\xd0\x6a\x62\xa8\xe3\xfb\xc8\xc2\x1e\xd9\x9a\x00\xa0\x8f\xf9\x09\x80\x00\xde\x02\x2c\x2b\x48\x1d\x81\xbb\x57\x72\x83\xc1\x53\x28\x70\x06\xb7\xd4\xe4\x18\xef\xe2\x73\xf1\xe2\xfa\xf5\x39\xe2\x9d\x30\xe3\xb3\xcf\x36\x70\x22\x90\xbc\xcd\x8c\x2b\x34\x1e\xde\x39\xab\xe5\x65\xb0\x5a\xae\x54\xe9\xec\xf7\x9f\xdd\x72\xcb\xe0\x37\xc3\x96\xf2\x63\x64\xde\x17\x52\x8f\x70\x5d\xe1\x50\x6e\xa4\x00\x7d\xe3\x62\x8c\x4b\x36\x44\x0c\x76\xb8\xc0\x35\x04\x5b\xa8\xa5\xba\x15\xa5\x50\x8d\xc6\xf8\x24\x35\x67\x57\xef\x46\x6b\x65\x4e\xe0\x92\x0b\x24\x0a\xac\x1c\x34\xec\x5a\xed\x89\xda\x2f\x92\xd9\xcf\x8d\x5d\x2d\xec\x2a\x34\x8d\x58\x63\x2a\x52\xda\x8e\xdb\xf3\xef\x9f\x77\x4e\x24\xbd\xf0\x9f\x27\x5b\x81\x8f\xcf\x6a\x9f\x9c\x10\x51\xfb\xfe\x5f\x28\x85\x48\x1b\x77\x4f\x04\x8b\xdd\x75\x6b\x80\xad\xa1\x73\xee\xc2\x91\xb6\x55\x03\x59\x9d\x7f\x08\xc4\xfd\x30\xa0\x15\x76\x12\x44\x34\x29\xb6\x75\x4c\x1c\x4b\x10\x61\xa5\x5f\xbd\xb3\x07\x4b\xa3\xe0\x1f\xcf\x4f\x29\x7e\xf7\xcf\x06\xbd\x1c\x1a\xc3\xdf\x78\x6e\xb7\x09\xe0\x22\xb2\x9b\x52\x11\x4f\xce\xd2\x09\xf6\xb5\xd9\x96\x55\x91\x4c\xfc\x0c\x27\xdf\xf5\x9c\xda\xf0\x31\xb6\xd6\xe9\x0a\x50\xbc\x1c\xc7\xd9\x76\x7e\x85\x0e\xcf\x38\x59\x9f\x38\xb2\x74\x61\x35\x44\x0a\x32\xbe\xa8\xff\x8f\x8f\x0f\x80\x64\xbb\x55\x6c\xd7\x51\x8a\xd2\x2e\x4c\x83\xb1\xb6\xe1\xd3\xd8\x40\x80\x41\x5a\x07\xed\xb1\x9e\x59\x37\xd2\x6e\x9e\xc3\x70\x5c\xa1\x9f\x0b\xb4\x90\xcb\xdb\x11\x6c\xc3\xab\x20\x55\xdf\xe9\xd1\x59\x0c\xd6\x32\x10\x1f\x8d\xa0\x7c\xc7\x42\xba\xa3\x31\x56\x47\x60\x9c\xd5\xbc\xcc\xd5\x72\xdd\xb2\x44\xe1\x43\x88\x1b\xd4\x3d\x99\xd7\xae\x39\x14\x93\x74\x35\xe1\xef\x83\xe3\x98\x92\xc4\x40\xdf\xaa\x4b\x50\x2a\x07\x80\xce\x07\x87\xce\x87\x08\xf3\x2d\x04\x83\x32\x07\xe2\x20\xa5\x27\x20\x25\xb7\x58\x54\xcd\x87\x05\x5e\xb8\x40\xc1\xf5\x97\xfb\xac\x6f\x3a\x5b\x4a\xce\x3a\x3d\x9d\x04\x21\xf3\x3c\x09\xfa\xa9\xfc\xf2\x97\x46\xf7\xe1\x81\xb1\xd3\xde\x83\x90\xa0\x18\x19\xf6\x4e\x30\xee\x25\xb4\x37\x73\x16\x84\x6e\x66\x5a\xfc\xbb\x11\x90\x37\xc7\xc7\xe5\x84\x1d\x41\x5c\x76\x31\x11\x8f\x20\x1f\x14\x51\x3f\x46\xe5\xef\xaf\x37\x26\x4e\x69\x3c\xbb\xc4\x60\x72\x91\xaf\x19\x58\xfb\x2b\x26\x67\xbe\x2d\x5d\x61\x84\x56\x3f\xba\x0d\xb6\x5b\xda\x51\x92\x7c\x7f\x6b\xc6\xed\x36\xb9\x5c\x8f\x27\xbb\x97\x3c\xca\xed\x88\xfb\x5f\xa2\x07\x73\xc7\xde\x97\x23\x30\x7d\x1c\xd9\xdd\xc6\xe9\xb8\xb7\x04\xf7\x4c\x9f\x06\x87\xac\xc7\x24\x1b\x12\x0c\x4e\x3a\x31\x1c\x4c\x5b\x79\x3f\x03\x8d\xec\x0f\x20\x57\xef\xa0\xf5\x21\xb1\x1e\x9e\x51\x4d\x59\x9e\x5b\x6b\xb7\x29\x0d\x76\x60\xf1\x4f\xa5\x76\xf7\x11\xe1\x14\x43\xd7\xa7\x16\xd8\x3b\xcc\xc7\xa0\xb7\xe9\x8a\x35\xcf\xfd\xe7\x76\xbe\xee\xfd\x70\xfd\x91\x0e\x17\xae\x46\x20\x21\x8e\x5c\x99\xd8\x7c\x42\x15\x29\xb2\xda\xf0\x55\x57\x86\x7a\xba\x94\x1e\x43\x86\xdc\xfd\xfe\x09\x44\x88\x4e\x28\x2e\xe8\x63\x0d\xab\xf7\x8c\x03\xf9\x5e\x58\x3b\x16\x82\x1c\x26\x2e\xd6\xa1\x92\x5e\x0d\x6a\x8a\x71\xc0\xc6\xc9\xc3\xcf\x87\x63\x20\x34\x7e\x2a\x9c\xa3\x45\xac\xa0\xf1\x74\x06\xe2\x38\x44\xa6\x75\x43\x44\x67\xd9\x3a\xea\x06\x7d\x42\xc5\xf2\xb6\x12\xa5\xdd\x2c\xae\x9b\x59\x21\xf5\xc2\x1a\x52\xaa\xc2\x1e\x88\xe5\xed\xf8\xcb\xdb\x74\xf6\x04\xcc\xc1\x5e\x2f\x1e\x98\x06\xa5\x63\x39\x40\x45\x52\x89\x0c\x73\x4f\x55\x29\xbc\x6f\xe7\x56\x18\x4d\xd9\xba\xb9\xcb\x69\x98\x51\x86\xe8\xf8\xd0\xf8\x8d\xb7\x63\xbe\xd7\x01\x8d\xab\xa7\x8e\x52\x6e\x09\xfb\xed\xc7\x5f\x5c\xe1\xa4\xa9\x22\xcc\xda\x0d\x2e\x4a\xd1\xe8\xb9\xd6\x6d\xdd\xdd\x42\x69\x64\x38\x82\x45\xd7\x72\x1d\xb4\x3a\x28\xb9\x1b\x58\xd7\xcd\x94\x20\xb9\x5d\x39\x02\xe2\x6b\xbc\x97\xca\x05\xa1\x51\xcb\xd7\x5d\x8e\x74\x44\x86\x0f\xaa\x12\x25\xaf\xe4\xd6\xf2\xe7\x90\xaa\x41\xdc\x8e\x2a\x79\x48\x1a\xbc\x13\x0f\xdc\x5b\x23\x77\x88\xd3\x31\xc5\xec\x2f\x87\x14\xb3\x77\x80\x6e\x24\x36\x18\x40\x46\x43\x39\x51\x5a\x83\xe3\xbd\xe4\x8c\xe3\x89\xe0\x2f\xeb\x05\x8d\x0e\x10\x70\xa0\x98\x5b\xf3\x8b\x3a\x01\x58\x04\x1e\x45\x8c\x80\xbc\x1f\xcf\xe1\x42\xb8\xbe\x17\xe7\x4d\x79\x57\xaa\x87\xf2\x9c\x2e\xa2\xb9\x81\xda\xc9\x47\x15\x2f\xb4\x80\x2c\x97\xae\xde\xbd\x64\x84\x09\x54\x5f\x47\x5c\x58\xc0\x25\xba\xd2\xb6\x68\x1d\x4e\xc0\x06\x29\xd0\x73\x03\x6f\x47\x1e\xba\xc2\xc3\x7b\x67\xee\x5a\x0d\x77\x06\x9e\x78\x2b\xfc\xae\x99\x89\xcc\x14\x7f\xa1\x43\xc7\xb9\x96\x79\x48\xbf\x73\xa1\xfc\x3c\xcb\x44\x65\x3c\x21\xb0\x72\xa3\x91\x71\xf8\x30\xc1\xa1\x28\xca\xaa\xe0\x92\xec\xf9\xb8\x76\xaf\x5e\xa8\x87\x5e\x21\xfe\xef\xd7\x6f\x5e\x3e\x45\xb9\x93\x25\x13\xcb\x99\xc8\x5d\x0c\x04\x9e\xee\x9e\x84\x18\x42\x2a\xa7\xc7\xce\xdd\xa5\x9e\x4e\x12\xbb\x83\xef\x2c\x8c\xa8\xe7\x24\x7f\x14\x61\xe4\xa6\x6f\xae\x01\x2a\x74\xd3\x0f\x09\x27\x78\xed\x2f\x20\x25\x05\x4b\x8d\x3c\x9a\xd8\x46\x84\x41\x95\x70\x42\xb9\xec\x47\xe0\x70\xe2\x97\xe4\xd0\x12\x70\x6a\x70\xe2\x52\x1e\xd5\x3c\xe4\x45\xf0\xba\xe6\x2b\x3c\xd5\x56\xb5\x5c\x4a\x23\xef\xc5\x60\x7c\xc3\x80\x3c\xa6\x46\x1d\x05\xf9\x41\x01\xc2\x20\x0c\x93\xf1\x62\x5a\x71\xad\xd3\x58\xbd\x56\xc0\x04\xf5\x15\xe9\x88\x71\x72\x5b\xef\xcb\x16\x86\xe7\x78\xc1\xbe\x6e\x68\x0a\x31\x00\x81\xf7\xc3\x75\x56\x47\xb2\x32\x90\xa2\xd1\xea\xa0\x87\xbd\xda\x7a\xcd\x92\xf3\xdf\xb9\x02\x84\x83\x9f\x76\x17\x64\x3c\x24\xad\xb0\xee\xe5\x1c\x8b\x47\x7f\x9a\x3b\xc6\xc9\x37\x09\x27\x2c\x47\x5c\x8f\xa3\x0c\x13\x7b\x14\x2d\xc4\xbd\x28\x3e\xcd\x0d\xc1\x9d\xb5\x48\xf7\xb0\x97\xaf\x6e\xae\xde\xbd\xbe\x7e\xff\xfa\xed\x1b\xa6\x0d\x2f\xff\x97\x3f\xce\x09\x8b\xd7\xd0\xd3\x00\x52\x56\x46\x44\xb2\x1d\x44\xac\xfc\x49\xe7\xea\xdd\x4b\x38\x7a\x84\xe0\x6c\xc4\x63\x7c\x70\x2c\x01\x5a\xe7\x12\xd6\x15\xc7\x5a\x8b\xed\x51\xbc\x53\xbb\x73\xe0\xda\xf3\xb0\xf5\x98\x8c\xbc\x93\x65\xfe\x68\x7c\xd4\xf6\x88\x89\xc9\x55\x11\x5d\xc1\xe1\x19\x88\x0f\x18\x1e\x94\xc3\xee\xe8\x92\x8c\x1e\x9f\x6f\x01\x83\x1e\x39\x00\x54\xb6\xe0\xfa\xe1\x2f\x01\x0e\xc8\x79\x27\xc5\x4f\x80\xf9\x29\xc3\xbd\x93\xe1\xd3\x70\x95\x1c\x81\x87\x50\xcb\x77\x12\x62\x5f\xc3\xb5\xd4\x66\x66\xa5\x75\x80\x7b\x40\x40\x89\xfe\xfb\x11\x2e\xf1\x17\x58\xd2\xd2\xbf\xdd\x6e\x12\xd7\xbe\xcb\xa3\xae\x3a\x8e\x82\x73\xd5\xd0\xaa\x7a\xc0\x5e\xf7\x9a\x9a\x96\x8a\x2e\xdc\xb8\xfc\x9f\x8f\xc0\x85\x33\x51\x53\xc5\x9f\xb3\xd9\xca\x5f\x2f\xa7\x83\x8f\xa9\xcb\x9c\xb0\xa1\xbf\x38\x2e\x50\x2f\xf0\xd9\x57\x81\xde\x96\xee\x22\x8a\xa7\xb4\x87\x53\x00\x4b\x45\x90\xe7\xc2\x64\x0b\x41\x9d\x7f\xc1\x41\x26\xf2\x49\x28\xab\xe8\xae\x4d\x37\xfa\x0a\xfd\x35\x14\x82\x9f\x84\x4a\xc4\x51\xfa\x26\x12\x1c\x7f\x95\xda\x0d\x47\x0c\xa4\xf3\xe3\x03\x5b\x62\x48\x3d\x82\xc0\x1e\xa8\x00\x02\x4a\x84\xda\xdf\x5c\x69\x2d\x7c\xaf\x05\x34\xe2\x5e\x5a\xd8\xa7\xc3\x41\xb8\x02\x2e\x8a\xa1\xb0\x9f\xdd\x78\xf6\x37\x5e\xcf\xf8\xad\x60\x57\x28\xe2\xaa\xf6\x2b\x27\x17\x55\xa1\x56\x4b\x20\x0e\x98\x62\xfc\x16\x4d\x35\x0a\x45\x9e\xf1\xec\xce\x6a\xa0\x72\x44\xc0\xb5\x1b\x25\x73\xa3\xb4\x96\xd8\xbb\x1b\xbf\x3a\x66\xab\x68\xe4\xb0\x02\x4a\x65\x98\xaa\xab\x05\x1f\x91\xcf\xe3\x2f\x37\x03\xa0\x50\x8a\xb4\x2a\x64\xc6\xb5\x30\x53\xf6\xb6\x84\xaa\xb2\xee\x87\x78\x89\x4e\xe2\x7b\x6d\xbc\xc9\xf4\x90\xe2\x4a\x70\x6f\x2b\x54\x63\xd7\x81\x3c\x98\x59\xe1\x2a\xc2\xfe\xd5\x13\x09\x4f\x90\x2f\x5d\xd0\x52\x0b\x68\x7c\x1b\x8e\x0e\x5c\x8f\x56\x44\x98\xd6\x47\x4e\x64\x78\xa1\x95\xab\x07\x4a\x81\xdd\x33\x51\x28\x3b\x8a\x6a\x7d\xd3\xad\x48\xb7\x65\xd0\xd0\x2d\x72\xf2\x83\xe7\xe4\x78\x81\xa2\x39\x99\x28\xfd\xa3\x10\xf5\xe4\xd8\xb2\x05\x85\x57\x22\x22\xd6\xd9\x9e\x52\xd5\x3f\x0f\x14\x8b\xe7\xc0\x03\x92\xad\x77\x57\xb1\x4c\xc5\x35\x56\x30\x19\xb8\xdd\xcb\xd5\x2d\x86\xab\x6d\x44\x0c\x60\x46\x62\x96\x8a\xd8\xbb\x08\xd7\xab\x80\x2b\x9e\x92\x78\xa3\xbb\xe4\xb1\xe2\x83\x29\x94\x57\x54\x9f\xe6\xe9\x48\x0a\x66\x5d\xa9\x87\x12\x12\x22\xc6\x98\xde\x83\xc2\x71\x27\x44\x85\x2b\x2d\x63\x1c\x28\x87\x81\x04\x3e\xe7\x81\xca\x03\xe1\x05\xb1\x53\xd2\x94\xdc\x9d\x70\x86\x69\xbe\xd2\x4c\xab\x43\x88\xcf\x92\x7f\x94\xcb\x66\x09\x59\x37\x19\xc7\x56\x93\xb0\xa8\x67\xc2\x3c\x08\x81\x9e\x98\x67\x97\xb0\xcd\x3d\xbb\xbc\xf4\x6a\x62\x48\xe0\x30\xb1\xa3\x28\x10\x88\x9d\x49\x57\xd8\x70\x35\x6c\xa1\xd3\xbe\x57\xb5\xd8\x24\x6c\x18\xfa\x38\x5a\xe0\x3a\xc2\xe6\xab\x99\x2f\xdc\xac\x4e\x2a\x85\x95\x28\x73\x51\x66\x2b\x36\xd2\x7e\x19\x14\x33\xba\x25\x9f\x15\x2a\xbb\xf3\x9b\x1b\x01\xc7\x03\x8e\xac\xb3\x62\x53\x5a\xbb\x8f\x21\xad\x05\xd2\x6f\x12\x72\x85\x97\xc8\xbb\xb7\x0f\xd0\x7b\x45\xc0\x31\x20\x13\x9a\xe9\x06\x9e\x43\x5d\xec\x1c\x83\x1e\x16\x1c\x44\xfa\x8b\x89\xfd\xef\xe7\xee\xcf\x67\xe8\x6c\x55\xf9\x17\xee\x17\xc8\x57\x56\x6d\x80\xb5\xd0\x95\x35\x82\xef\x45\xb1\x72\xa1\x62\xae\x0c\xd5\xb3\x64\x03\x83\x42\xe2\xa0\x06\xdf\xe3\xe6\x93\x50\xd3\x17\xb6\x47\xaa\x00\x8b\x6f\x53\xfa\x51\xf0\xec\xb1\xf9\xec\x4f\x36\x30\xd7\x7d\xb4\x89\x9d\x4d\x30\x9b\x60\xba\x46\x07\x55\x0a\x96\x20\x38\x8d\xd1\x1f\x85\xb4\xb5\x64\xc7\x7f\xd9\x17\xcf\xce\x34\x54\x9c\x71\x01\x5e\x31\x9c\x64\x65\xec\xa7\x66\xde\x5d\x3d\x9b\xac\xd7\x35\x14\xbf\x00\xfa\xa6\x5f\xd7\xd0\x18\x58\x45\x67\x78\xa0\xe7\xf0\xa9\x16\x6e\x3b\x89\xc4\xca\x4e\x70\xc1\x8b\x39\x5e\x85\x2b\x2d\xba\x9a\xec\xd9\x3a\x55\x86\x5a\xba\x57\x9d\x3d\xdb\x55\x97\x01\xcc\xbf\x7b\xa4\x62\x6b\xca\xae\x8b\x04\xff\x20\xc2\x91\xc6\x6a\x0c\x32\x9a\xa7\x81\xda\x46\x2e\x85\x36\x7c\x59\x6d\xb1\x35\x47\xf2\x14\xb0\xb0\xf3\x85\xbd\x0f\x39\xb4\x0a\xf2\xdb\xcf\x82\x31\xad\xf8\x0e\xb5\x63\xc7\x87\x85\x1e\x7b\x0e\x6d\xac\x3d\x16\x18\x02\x18\x71\x4e\xd8\xc4\x77\xa9\xd9\x5b\x84\xf5\xc9\x9c\x21\x10\xdf\x20\x3d\xde\x8a\x6c\x9f\x1f\x70\x7f\x1d\x7d\x7c\x40\xb5\x82\x94\x75\x27\xea\xf4\x28\x31\xf8\x6d\x38\x46\xb8\xcf\x9f\x80\x75\x78\x44\xb9\x1b\x38\x43\xc8\xb9\x8f\x60\x0e\xb6\xe0\x7f\x92\x29\xd8\x16\xcd\x35\x8a\x2d\x38\x37\xc6\x98\x81\x47\x13\x2b\x5f\x5d\xf2\xdc\x29\xe9\x73\x8a\x83\x3c\x1f\x77\xa2\x78\xe3\x00\x44\x7d\x9a\xfa\xfc\x56\x64\x03\x59\x4a\x47\xd1\x96\xd4\xd4\x83\x47\x55\x2e\x23\x1f\xd0\xf8\x34\x63\x39\x1f\x82\x01\x59\x44\xf1\xe8\x7e\xe4\x79\x4d\x57\xe3\x00\xc1\x7f\xbc\x5d\x06\x71\xf8\x6c\x3c\x61\x21\xee\x25\xeb\x74\x48\xdc\x8f\xb8\x11\x50\x96\x4c\xf3\x64\x04\x76\x18\xc4\xa3\x03\x36\x10\x45\x7b\x14\x22\x7b\xfa\xf8\xc2\xe7\x7b\xd1\x14\x0f\x11\x3c\x02\xbb\xc9\xa9\xfd\x26\xa6\x08\xad\x5e\x34\xf3\x93\x27\xe4\x29\x6d\x3f\x49\x7c\x9c\xa5\x7a\xf0\xa1\xe9\x18\x28\xf0\xc0\x7e\x80\x36\x13\x6d\xcf\xe6\x9f\x76\x25\x97\xbb\x75\xf9\x47\xa3\x0c\xef\xa9\xb0\xbc\x99\x78\x09\x84\x9e\x94\xdf\x3e\x90\x2c\xfd\x6a\x3a\x76\x37\x48\xc7\x82\x90\x80\xb4\x37\xd5\xbf\xe1\x81\xeb\x4a\x75\x15\xd7\xe8\x75\x41\xc7\x51\x36\x20\xf6\xe5\x4f\x81\x4a\x1d\x87\x25\x53\x46\xe9\x9a\x51\x26\x71\x8c\x69\x9c\x29\x4c\x21\x2f\x04\x8b\xda\xc8\xf6\xa0\xec\x90\xed\xe2\x82\x1b\x68\xd4\x11\x49\x9a\xc4\xac\xf6\x31\xf9\xee\xc6\xb1\x7f\x2d\x8d\xb9\x34\xf2\xd1\xf9\x30\xb5\x0d\x42\x42\xe1\x77\x99\x6a\x4a\x83\xb4\x98\x24\x05\x8d\x77\x11\x98\xac\x9f\xc5\x50\x07\x82\x57\x26\xae\x02\x5b\xc8\x79\xe8\x9a\x39\x97\xb7\x3f\xf2\x6a\x37\x01\x6a\x09\x48\x4f\x06\x96\x34\x3a\xfd\xe4\x06\x72\x0e\xc3\x0a\x5d\xa2\x8f\x41\x31\xf1\xd1\x9e\xfc\x45\x8e\xe1\x73\xd8\xf9\xdb\xf0\xc2\x17\x87\xf1\x57\x3e\x28\x3b\x48\x3b\x2b\x21\xb2\x4c\xd9\xc6\xa2\x14\xe9\x30\xbd\xd7\x46\x77\x2b\x4e\xb7\x90\x8d\xc2\xb9\xd0\x50\xb3\x43\xc4\xb5\x33\x2c\xf1\x3c\xcc\x56\x4f\x23\x47\x65\xa8\x62\xd5\x33\x65\x77\xe2\x4b\x09\x18\x1c\xf6\x22\x85\xee\xec\x1d\x87\xad\x5b\x13\x9b\xf0\xf4\xe1\x59\x83\x78\x92\x58\x53\x46\xd7\x36\x98\x9e\x76\x41\x54\x6a\x84\x63\xfe\x70\x4b\xa1\x52\xf9\x6f\x73\x11\xf8\xe6\x71\xed\x2e\x87\xf4\x39\x69\xd4\x09\xa9\xd3\x09\x7b\x55\x2d\xc4\x52\xd4\xbc\xb8\xa1\x6c\x3f\xb7\xa5\xba\x9e\x8b\x6e\x2e\x76\xd3\xc5\xce\x85\x23\x56\x16\xf9\xf5\xd2\xe8\xbc\x58\x80\xf7\x5a\x47\x49\x75\x0a\x4a\xe3\x1b\x9e\xb8\xf8\x68\xd7\x12\x76\x7e\x5c\x72\x09\x17\x33\x28\xa6\xdd\xd9\xa0\xb5\xc5\x65\xe1\x0a\x2c\xa6\x40\x5a\x9c\xf5\x9b\x51\x94\x05\x14\x97\x47\x74\xf6\x8c\x73\x6a\x9e\xe9\x6e\xf3\x49\xfa\xd8\x93\xd3\x0d\xce\x7d\xa3\x5e\x70\xdd\xac\x4a\xbe\x94\x19\x54\x89\x8a\xfa\x42\x48\xd3\x82\x28\x6b\x01\xa7\xe9\x24\xf3\xb6\x0f\x25\x6c\x56\x68\x87\x48\x34\x8f\xdf\xf5\xb3\xb6\x50\xbb\xf0\x51\x50\x0a\xee\xe8\x67\xcf\x91\xb1\xa0\x02\x6f\xf5\xa0\xae\x71\xb1\xb9\x4f\x40\xdf\xd0\xe1\xf6\xa6\xd3\xcb\xf9\xa8\x6a\x87\x46\x65\xe0\xe9\xf9\x2d\xaa\x9f\x77\x9e\xac\xbb\x6f\xc2\xb8\xac\xc3\x06\x17\x01\x3d\xca\x2e\x1c\xe3\xbc\xdb\x36\xec\x39\x3d\x8c\xe9\xa7\xb2\x0f\x47\x0e\xa4\xc4\xd3\x72\xea\x25\xd2\xf2\x60\xfd\xa6\x57\x4b\x4a\xec\x5d\x16\x0e\x5e\xfc\xb5\x2d\xc3\x7e\xf8\x5b\xae\xa1\x61\x9d\xdd\xb3\x86\xda\x33\xe9\x5d\x4e\x3e\x70\x77\x93\x65\x3b\x0e\x7f\xb7\xb2\x82\xa3\xe4\xe9\xae\x2e\x2d\xb2\xfa\xb4\x3b\x0e\x8e\xf8\xdb\x5c\x3e\x37\x34\xb7\x83\x9d\xf6\x10\xa0\xe3\x5c\xfc\x19\x92\xfa\x18\x2b\xc7\x4d\x62\xec\xce\x33\xb0\xd4\x53\xd4\xb7\xdd\x75\x7a\x7c\x4c\x8f\xb0\x36\xc0\xf9\x79\xda\xc5\x01\x43\xfe\x56\x57\x07\x4d\xee\x80\xcb\x03\x20\x9e\x7a\x7d\xd0\x34\xf6\x5e\x20\x09\xf2\xdb\xac\x90\xc8\xbc\x7b\x64\xdb\x0c\x5f\x81\x3f\x47\xdc\x7d\x6c\xbb\x50\xf0\x42\xc4\x1f\x2c\xa9\x60\x18\x34\x16\x51\xcb\xca\xd8\xc3\x23\x2f\xb2\xa6\x40\x17\xfd\x6f\x66\xcd\x1c\x8f\x89\x38\xb2\xce\x54\x25\x26\xec\xaf\x42\x9b\x57\xf3\xb9\xaa\x71\xe5\xbc\x51\x26\xfa\x05\xde\xd9\x91\xa3\xf7\xd8\xc3\x3f\x7d\x06\xae\x90\x99\xa0\xd5\x2b\xa2\x51\x46\x72\xce\x3c\xa8\x14\x24\xf5\xbb\x01\xc0\x67\x01\xf5\x33\x84\x1a\x77\xb0\x09\x97\xbe\x67\xc9\x2c\xcf\x1c\x02\x9b\x84\xc0\x2c\x84\xac\x1f\x51\x75\x26\xd3\xbb\x56\x70\x9b\x5c\x2a\x03\xe9\x81\x32\x93\x76\x25\x60\x0b\x9f\x15\x7a\x95\x7c\x7a\x02\xb4\x80\x44\x95\x44\xde\x1d\x00\x3c\xc6\x69\xb6\x83\x73\xcc\x29\xd0\x2e\x37\xf2\x96\x34\xcc\x9a\xa8\x94\xba\x2c\xfb\xf9\x92\x6f\x38\x27\x7b\x8f\x51\x3e\xa8\x89\xed\xd3\xde\xad\x24\xee\x9f\x3e\xca\x28\xd9\x38\xa7\x56\x89\xda\xf6\x8c\x88\x6b\x3b\x70\xcc\x7e\x8a\x7b\xc8\x11\x39\x36\x82\xfe\x5d\xa6\x3d\x71\x8e\x8d\x94\xa9\x13\xa9\x5b\xdf\xa1\xa2\xbc\x75\xfa\x36\xfe\xe9\x38\x0a\xd7\x84\x11\x80\x70\x30\x8a\x3e\x88\xc6\x8d\x90\x1f\x52\xb9\x67\xe9\x1c\xbd\xba\xa5\xf6\x86\x3e\x66\x07\xa4\xde\xfb\x6a\xbb\x57\xac\xad\xa2\xde\x35\x66\x88\xd9\x17\x87\x5c\xf1\x4f\x58\x97\xfb\x7b\x01\x6a\xba\x26\xf2\xf6\x74\x1d\x6e\xef\x22\xff\x39\x9b\xf3\xa2\x70\xa0\xff\xed\x6f\x97\x9d\xbf\xff\xd8\x0a\xbd\x97\x91\x1b\xf5\x43\xcf\x27\x7d\xc1\x03\xfb\x2a\x88\xc8\xc0\xde\xea\x9c\x39\x6a\x56\x2d\xee\x55\x5d\xee\x71\xb8\x59\x7a\x29\x78\x5e\xc8\x52\xdc\x44\xdd\x41\xeb\x5e\x46\x52\xde\x6f\x8b\xe9\x1d\xfe\x6e\xcf\xdb\x1e\x3a\x8c\xf0\x47\xf7\x71\xa9\x27\x8e\xa1\x6f\xc7\xde\x4c\xbc\xb5\xbc\x0d\x0b\x6e\x9b\x0d\x60\x33\x6f\xbd\xd4\x8e\x62\xee\x01\xd5\x3f\xfa\x3c\x34\x5c\x1e\x33\x51\xde\xcb\x5a\x95\x10\x87\x0a\xe5\x27\x36\x2b\x77\xfa\x3e\x0a\xc2\xc9\x54\xa9\x9b\x25\xc4\x88\xc0\x6c\x21\xe2\x4d\x96\x16\x38\xbb\xe7\x35\x4e\xf5\x97\x37\x2a\x17\xb1\x42\x1f\x7b\x14\x72\xbe\xb8\xae\x6e\x8a\x5a\x34\x61\xd3\xe5\xac\xe0\x35\x74\x17\x8c\xa6\x85\x29\xf1\xbc\x96\x80\x1f\x66\xf7\x46\xd9\x14\x70\xd3\x87\x5e\x20\x77\xc7\x07\x2a\xd5\xd4\xdc\x1e\xd6\xa1\x7f\x24\x84\xd5\xb8\x68\x32\xf7\x7a\xb0\x51\xd3\x24\xd3\x98\xa2\x7e\x58\xec\x0e\x8e\xe8\x6a\xaa\xa7\xe1\xc0\xd2\x06\x71\x27\x30\x11\x85\x52\x05\xc3\x20\x1b\xc2\x2e\x33\xb5\x5c\xaa\xf2\x02\xdf\xef\xa4\x95\x0e\x33\x1b\x2a\x4c\xba\x5b\xe6\x7d\x58\x7e\x2f\x79\x7b\xe2\x4f\x88\xe1\x58\x75\xe8\xec\x55\x79\xff\x7d\xad\x96\x67\x3b\x09\x00\x41\xec\x13\x82\x7d\x04\x20\x06\x1b\x84\xe0\x58\x02\x80\x2d\xa7\x97\x95\x59\x9d\xe3\x94\xb6\xe3\x39\x5c\xb0\x87\xa2\x33\x44\xb1\xbc\x81\xe8\x3b\x00\x8b\xa6\x1b\xfe\x6e\xe7\xb1\x21\x84\xb1\xa7\xd1\x2a\x79\x63\x31\xbc\xbf\x44\xa8\x16\x54\xab\x04\xbf\xbf\xf0\xef\x28\xc6\xaf\x76\xa3\xce\x16\x41\x9c\x2d\xaa\xb8\xc0\x4d\x9a\xf6\xa6\xa8\x4d\x1a\x2e\x0e\xd9\xfc\x21\x4a\x28\x77\xc0\x29\x66\xc0\x34\x75\x19\xe8\x50\x48\x4d\x3a\xe7\x6f\xf2\x5e\x60\x28\x9e\x2f\xa6\x0f\xc5\xa7\x05\xfd\x41\xce\x41\x84\x36\x61\x51\xf7\x41\xcc\xa8\xff\x77\xc3\x0b\x1f\xe9\x49\x4d\xcb\x01\xf0\xfb\xe0\x11\x8f\xe2\x6c\x67\x2b\x26\xcd\x19\x3a\xb6\x64\x46\xa1\xa1\x1e\x57\x6b\xe7\x52\xa2\xff\x5c\x42\x3f\xae\x89\xaf\x86\x9e\xe6\xd1\xc7\x31\xa6\xaa\x96\xb7\xf8\xb6\x5f\x74\x37\xbd\xf2\xde\x17\x73\xba\x9e\xa5\x2f\xae\x5f\xb3\xa5\x30\x1c\xba\x0a\xff\xfd\xfd\xfb\x6b\xa2\xe4\x18\xde\xd6\xf7\xa2\xa6\x2a\x62\xae\x5b\x95\x5d\x99\xef\x71\x09\xd7\xbc\xd4\xc0\x5d\xac\x07\x15\x1a\x92\x39\x56\xb1\x2f\x2f\xbf\xc6\x22\xd9\x90\x38\x2d\xca\x9c\xd4\x4d\xae\x84\xc6\x2e\x8e\xcb\xaa\x00\x0b\x2b\xa0\xb8\x5e\x66\x5e\x6b\xdd\xd8\xa5\x41\x13\xc1\x13\x09\x69\x88\x17\xd7\xaf\xa7\xe9\x83\x44\x70\xf0\x91\x0e\xc6\x06\x74\xbf\x52\x73\x8b\xe5\xd6\x26\x05\xe4\x3d\x44\x2d\x66\xda\x54\x87\x3e\x26\xe7\xa1\xcb\xf3\x39\xb6\x4b\x3b\xe7\x65\x7e\x5e\x0b\x6d\x78\x6d\xc6\x34\x84\x83\x46\x30\x96\x07\xdd\x08\x5f\x82\x82\x23\x41\x72\x5e\x08\xa3\x17\xac\xe0\x3a\xaa\x78\xe1\x2a\xe0\x50\xeb\x16\x9f\x38\x53\xd5\xe2\x5e\xaa\x46\x53\xc3\x97\xf1\x51\xe8\x9c\xbe\xa0\xe2\x17\xb5\x50\x95\x28\x9d\x71\x37\x38\x3e\x9a\x78\x6b\x71\x98\xb8\x38\x21\xe8\x36\x66\x37\x08\x59\x36\x90\xcb\x26\xed\x79\xb9\xbc\xb5\x62\x23\xe7\x74\x9d\xab\x5b\x61\xed\x95\x92\x25\xf6\x36\x97\xcb\x2d\x43\xdb\x7b\x1b\xcf\x74\xb8\x68\x87\xf2\xcd\x2d\xce\x47\x17\xc3\x5e\xc3\xc6\x1e\x26\x52\x09\x0f\xdf\xde\xbb\xc3\xc6\x9d\xf9\x14\x73\x89\xb3\x8a\xd7\x46\x66\x4d\xc1\xeb\x7e\x4e\x49\xa7\x54\xe9\xd0\x0f\xdd\x10\x12\xf2\xb3\x05\xaf\x2a\x01\xa1\x70\x98\x02\x4f\xcd\xfb\x5a\xf8\x42\x82\xe0\xac\xa7\x84\xf4\x81\xb8\x62\x15\xd4\xb9\x4b\x3a\x3c\x7f\x20\x62\x6f\xcf\x16\xd7\xd9\x88\xe7\xbe\x03\xca\x24\xee\x6b\x14\x1a\x21\xa5\x54\xc0\x18\x13\xc2\x66\x0b\xee\xf8\x3c\x49\x87\x32\x16\x7d\xf7\x0b\x3c\x13\xf2\x1e\x73\xa3\x62\x8c\x7c\xe0\x03\x61\xb5\x0e\x17\x1c\x86\x36\xe5\x56\x61\x1f\x00\x01\x35\xc0\x49\x69\xe3\x70\x29\x38\xa8\x93\x14\xe0\x39\xf5\x0d\xca\x9b\x1c\x2e\x76\x88\x35\x65\x7b\x0e\xc4\x63\x18\xe1\x9c\xea\xbc\xef\xc1\x5a\xdf\x13\xd4\xfb\x2a\xe4\x9c\x51\x53\x7e\x6d\x54\xa5\xd9\x52\x84\x94\xb1\x38\x18\xd2\xd9\x11\x9e\x80\x5b\x2f\xc3\x50\x44\x77\xf3\x48\xf4\xc9\x99\x26\x33\xd2\xe5\x1a\xfa\x86\x5c\xa8\x21\xfd\xbc\x48\x1a\x26\x54\xdb\xb3\xc0\x0e\xb6\xee\x71\x8f\xd2\x54\xb4\x5a\x09\x23\xec\x56\x21\x0d\x20\xa5\x93\x89\x42\xbc\x69\x84\x1d\xdc\x87\x1e\x92\xc7\xda\xda\x4b\x58\x78\x60\x4b\xb6\x3a\xa1\xa5\xa2\x53\x28\xfc\xae\x2f\x25\xd2\xdc\xd7\x8f\x84\xd2\x64\xaa\xce\xc5\x36\x9c\xeb\x82\xc3\x14\x45\x87\x34\x59\xe7\x82\x67\x0b\x86\x11\xc4\xd6\x3c\x2c\xa5\x91\xc1\x7d\xcb\x4b\xbb\x7e\xa9\x3f\x2b\x31\xcf\x92\x9f\x90\xa6\x39\x44\x9b\x27\x56\x61\xa1\xfd\x90\x80\x61\x1f\x45\x17\x64\xd1\xdd\xd9\xe7\xa1\x50\x14\xca\x00\x14\x7c\x42\xe9\xa2\xcc\xb4\xf6\x47\x28\x67\x05\xd5\xac\x44\x64\x60\x4d\x4f\x5d\xdd\x2b\x3b\xd5\xaa\x56\x79\x93\x39\xf4\x1e\x6a\x69\xb0\xc1\x3d\x8f\x8a\xe1\xb0\x5b\x55\xab\xc6\xc8\xb2\x7b\x13\xda\x73\x04\xd9\x2c\x19\x90\x87\x50\x2f\x29\xb6\x42\xd4\xe3\xdb\x4e\xa4\xef\xfb\xc3\x9a\x24\x9f\x75\xeb\xf1\x16\x2b\xb8\x04\x43\xba\xf5\xbd\x37\x7f\x4c\x2d\x85\xdd\xdc\xd8\x5f\x95\xc1\x4e\xf9\x4b\xfe\x2f\x72\x19\x5a\x66\x2c\x65\xa9\xea\x40\x77\xec\xa3\x67\xb7\xd3\x19\xa8\x24\x59\x1a\x71\x2b\xb6\x2f\x77\x86\xe8\x7c\x18\xb0\x41\x5f\x72\xb1\x54\xe5\x8d\x30\xe7\xdf\x73\x59\x88\xfc\x5a\xe5\xce\xcd\xde\x4b\xc8\x4a\xff\x4a\xdf\x80\xa7\xbe\x9d\x94\x67\x67\xb9\xf2\x6d\xee\xe0\xc0\x29\x72\x96\xe3\x07\x95\x2b\x7e\xb0\xe9\xc8\x97\xb9\xc7\x86\xfd\x77\x33\x13\x75\x29\xac\x3c\xe5\x52\x9b\x5a\xce\x9a\x70\x9e\xa5\x43\xb0\x3d\x92\xf9\x79\x84\x12\x0b\x90\x4b\x09\xed\x56\x3a\xe7\xde\x7e\x5d\x54\xe9\x0b\xc4\xf4\x83\x16\x66\x98\x50\xef\x54\x51\x58\xb1\xde\x89\x3e\xf4\xad\x2f\x96\xdb\x94\xa5\xc8\x84\xd6\x1c\x2f\x43\xac\xa1\x77\x58\x1a\xb9\x33\x19\x6f\x8c\x5a\x62\xca\xf4\x52\x96\x72\x69\xcf\x91\x98\xe4\x2f\x75\xdd\x54\x98\x42\xe1\xb0\x53\xf3\xd0\xe6\x42\x31\x1e\x26\x7f\x38\x2a\xbe\x51\xb9\xb8\x11\xeb\x8a\x1b\x6e\x22\x65\x83\x8d\x05\xa1\xf5\x4c\xa6\xec\x21\xf1\xa3\x93\xb4\x43\x13\x2f\x91\x2e\x56\xaa\x5c\x44\x3b\xae\xeb\x79\x91\xda\x37\xfa\x70\xa4\xda\x6b\x41\xc6\x54\xd2\xd8\x58\xee\x48\x44\x32\xb1\xbf\x49\xcd\xc3\x04\xc8\x53\xf2\x33\xe6\x36\xa7\xb4\x8c\x93\x28\x2d\x80\xf0\x34\x6b\x17\x60\x8a\x0b\x0f\xf0\x4c\x78\xb7\xe5\xb5\x1a\x73\x60\xd8\x62\x71\xcb\xf2\xf6\x27\x97\xf8\xb2\x35\xc1\x29\xdf\x14\x6e\x93\xec\x84\xb1\x31\x0c\xf7\xb9\xab\x5e\xdd\xd3\x8b\xda\xd4\xdc\x88\x5b\x28\xee\x91\x0c\x7e\x44\x21\x4e\xc6\xd9\x5f\x50\x43\x55\x8e\x77\x62\x4d\xab\x55\x20\x5c\xf7\xdd\xe8\xa7\xb4\xf6\x9d\x2a\x72\xaa\x03\x50\xe6\xa1\x85\x2b\x96\xad\x54\xa5\xd8\x5c\xc4\x74\x17\x01\x7e\x99\x56\x4c\xa1\x4b\x4d\xe7\xc0\x25\x5e\x8d\xa4\x98\x07\xb5\x8e\x62\xe3\xe4\x6d\xe0\x83\x8d\xb4\xf3\xd2\x16\x6d\x95\xa7\xa5\x5d\x22\xd2\xc7\x20\xa0\xb8\x97\xd6\xb0\xf9\xbb\xd4\x46\xd5\xab\x1f\xe4\x52\xf6\x47\xbd\xb7\xe8\x98\xaf\x23\x5d\x94\x3c\x75\x38\x52\x65\x85\xe0\x25\x6b\xaa\x08\x8b\x33\x1d\xe5\xf1\x50\xf1\x2a\x1e\xba\x7c\xa4\x6f\xfe\xdf\xa9\xd5\x25\xd3\xba\x67\xc2\xff\xf7\x80\x04\xbd\xae\x95\xe5\x28\x1e\x44\x6e\x32\x5e\x0c\xf9\xf8\x37\x12\xd4\xc9\x46\x15\x43\xd4\x1e\xe2\xe1\x6d\x9c\x08\x9b\x78\x4c\x8a\x8f\x81\x71\x27\x4c\x4e\xc5\x34\x79\x5c\xac\xe0\xa1\xdd\x5a\x86\x38\xe3\xea\x72\xbc\x4c\x8b\x36\x49\x8d\x5f\x8e\xdd\x7f\xc6\x2a\x04\x75\x3f\x90\x08\x35\x9a\xe4\x35\x41\x39\x26\x89\xdd\x18\xe8\x6c\x02\xb2\x42\xf4\x0c\xe3\xf5\x4c\x9a\xda\x5a\xb4\x65\xb3\x9c\x89\xda\x1a\x03\xe8\x94\x01\x73\x32\x17\x1a\x7a\x89\x68\x63\x55\x42\xde\x80\xc7\xb6\x46\x3d\x11\x67\x9c\x46\x55\x14\x61\xa8\xc6\xd8\x33\x9a\xd4\x8b\xd1\x5b\xd6\x20\xbd\xff\x4b\xcd\xf4\x24\xae\x8f\x34\x61\xb5\x38\xe7\x39\x56\x42\x1a\x24\xfd\x7f\xa9\x99\x23\x34\xbc\x8b\x27\x61\xb8\x3e\x02\x50\x2e\x36\x04\x13\x57\x4b\x55\x9e\x2f\xc3\x25\x19\xc3\xcd\x6c\xe4\x7d\x6e\xc5\x6b\x5e\x14\xa2\x60\xff\x52\x33\xbc\xca\x0b\xb4\x84\x22\x48\xad\x6b\x29\x6a\x78\x31\xf7\x1f\x4a\xbd\x44\xb3\x8b\x2a\x86\x71\x17\xa7\x88\x85\x33\x2c\xd2\xd2\x74\x2a\x25\xe2\x50\x76\x9e\x74\x2d\x82\x44\xa1\xfb\x27\xaa\x47\xc5\x30\xa7\xfd\x47\xac\xc0\x61\x5c\xeb\x5b\x70\x15\x44\xdd\x06\xff\x4b\xcd\xce\x34\x95\x94\x6d\x41\x0d\x99\xbd\x6d\xe3\x6d\xf0\x5e\xa5\xd2\x17\x96\x14\xbd\x8c\xc4\x38\x1d\x62\xe4\x6d\xcd\x33\x31\x6f\x8a\x10\x21\x37\x8e\xa3\xbe\x60\xfa\xbf\xd4\x6c\x2c\x97\x80\x39\xde\x05\x20\x62\x44\x7c\x4b\x3b\x60\x88\x28\x2c\x43\x3a\xd5\x40\xda\x6e\x5a\xfb\x10\x60\x7a\x5a\x45\x35\xfa\xe2\xdc\xea\x71\x2e\x94\x75\x34\xc3\x13\x13\x2c\x70\x72\xcb\x73\x7d\x07\x27\x65\x0c\xcc\xdf\x48\x2f\x38\x59\x00\xb1\x8c\x8a\xa1\xe1\xb1\x9b\xeb\x3b\xcd\xb4\x5a\x0a\xa8\x20\x08\x70\xfd\x64\xe1\xfa\x53\x61\x86\xb9\xbf\xe7\xda\xe4\x67\x09\xd1\xb5\xa1\x52\x1c\x8e\x62\x14\x5e\xb4\xab\x32\x13\xe4\x09\xb3\x14\x62\x2f\x60\x5a\x34\x80\x55\xfd\xfe\xe2\xcb\x53\x57\x7c\x14\x59\x83\x1d\x08\xc3\x0c\xf6\x91\x47\xda\x33\xd8\x8d\x30\x93\xb6\x8e\xf0\xb6\x6c\xa4\x20\xd2\xa7\x83\x64\x8f\x92\x7d\xfb\xf5\x0f\xc0\x56\x65\xda\x72\x9f\xc6\xa1\xcb\x08\xd7\xa5\x33\xfd\x66\xd3\xfe\xd0\x2e\xf3\x8c\x05\xa4\xe2\x79\xb2\x3f\xbe\xbb\xf9\x9c\x3d\x40\x21\xcc\x76\x5b\x00\x49\x8e\x43\x77\x0b\x40\xa1\x62\x56\x1b\xbc\xbb\x21\x16\x48\xf0\x88\x06\x35\x63\x47\x84\x12\xa2\xb8\x1c\xa9\x48\x27\xd4\x66\x8a\xec\x4a\x0e\xa6\x2c\x40\xfb\x99\xfc\x3c\x5e\x0b\x95\xb1\x16\x02\x65\x89\x55\x97\xe9\x32\xf1\xdd\x8d\x6b\xf9\x03\xdd\x4d\x89\x2e\x2d\x3c\xdf\xdd\x9c\xb5\x1b\x0d\x4c\xdc\xd7\x7d\x4a\x2c\x3e\xd2\xd1\x4f\xe4\x96\x6f\xd7\xa2\x6d\x4b\xd7\x17\x03\xd2\x45\x36\x68\xdf\x89\x2b\x91\x32\xbb\x0e\x67\x5c\xcb\x8c\xc9\x25\x86\x0a\x8e\x95\x21\x77\x2b\x10\x7d\x6d\x89\x07\x7e\x6a\x67\x01\x47\x04\x87\xd6\x15\xee\xbd\xf1\x39\x39\x7e\x54\xaa\x40\xe9\x88\xc5\x99\x96\xe5\x6d\x21\x42\x80\xd2\x94\xfd\xc8\xef\x04\xf3\x0e\x55\xbf\x5e\x49\x08\xeb\x06\xda\xb2\x60\xfc\xd0\xcd\xdf\xdf\xfe\xf4\xc3\x4b\xa6\x05\x80\xc2\xd2\xb4\xb5\xd0\x95\x2a\xb5\x40\x1d\xf4\xef\x46\xd4\x72\x64\x15\xbe\x51\xf4\x6e\x15\x05\xec\x5d\xe0\x9b\xc8\xdf\x4a\x30\x1e\xb7\x9a\xc7\x18\xcb\x25\x0a\x5a\x21\xb4\xde\xb0\x68\x5b\xd3\x60\x7f\x7c\x77\xf5\x39\x93\x3a\x24\x22\x40\x1d\xba\x81\xe5\xdc\xbb\x94\xaf\xfa\x97\xb2\x0f\xf6\x5b\xbb\x9c\xc3\x52\x1e\xbd\x32\xb2\xb1\x0c\x72\x8b\x74\x77\xce\x04\x5d\xdd\xab\x3f\x47\x1d\x63\xd6\xd3\x3d\xb0\xc9\x25\xa5\xb5\x8b\x5c\x46\xee\xb3\xf5\x6a\xae\x47\xad\xc5\x2a\xed\xaa\xab\xd2\x42\xbe\xe1\xd5\x78\xb5\xd6\x51\x69\x9d\x1d\xf3\x00\x9c\xdb\x4e\xab\xf5\x33\x6f\x84\x82\x0b\x09\x64\xdb\x29\xb8\xb5\xbd\x09\x3a\x31\x98\x7f\x05\x04\x5e\x2f\xa9\xe8\x51\xa8\x7f\x63\xa7\xe9\xee\x9c\x64\x46\x09\x18\x18\xf1\xa2\xee\x65\x2e\x72\xc4\x66\x4a\xdf\x3a\x93\xd0\x08\xed\xca\x08\x4b\x38\xd6\x32\x59\x52\x37\x85\x18\x1a\xc4\x98\x95\x78\xbf\x57\xab\xe6\x76\xc1\xde\x5f\x5d\x4f\xd8\x4f\x2f\xaf\x01\x8b\xbf\xbf\x7f\x7f\x3d\x5a\x3b\x8e\xe6\x1c\x36\x91\x99\xab\x9a\x49\xad\x1b\xa1\x59\x21\xef\x44\x54\x19\x29\xd4\xf2\x71\xc9\x0e\xbb\x70\xb6\xa9\xe7\x50\x94\xd1\x59\xac\xf6\x20\x8b\xd7\xa7\xae\xe7\x23\x67\x18\xf3\x86\x68\xc4\x58\xb8\xa1\x77\x88\xb6\x1c\x60\x3b\xb0\x0d\xb4\x76\x98\xa7\xef\xd2\xea\x2b\x48\x52\x25\xa8\xfe\xb8\xcc\xb1\x06\x7d\x97\x11\x37\xf6\x1c\x3d\x6f\x0a\xb0\x06\xfe\xda\xd4\xda\x6c\x74\xdb\x44\x9f\xb0\x5f\xee\xfe\xa4\xa7\x52\xfd\x4a\x42\x1a\x3f\x9a\x37\x65\x86\x3e\x12\x69\x56\xec\x97\xe8\x11\xbc\x8b\x8d\xbe\x70\x44\x72\xaf\xc4\x87\x83\xf4\x58\x20\xee\x45\xe9\x7a\x8d\x2e\x04\x2f\xcc\x62\x45\x16\xe8\x4d\xa1\x1e\x36\xc5\x39\xc7\x58\x75\xfc\x8e\xd7\xee\xac\x7c\xad\xf2\x1f\x79\xc9\x6f\xe1\x6e\x80\x8a\xfd\x5a\x41\x9c\x59\x14\x63\x2f\x90\x65\x82\xd4\x40\xc3\x10\x67\x88\x45\xeb\xf1\xda\xba\xaa\x05\x34\x51\x82\x2e\x70\x62\xce\x9b\xc2\x30\xaa\x5a\x76\x55\x70\xad\xed\x96\x86\xba\x83\xca\x65\xe1\x82\xd5\x52\x95\xdd\x2b\xda\xa1\x35\xa5\x69\x52\x3d\x16\x47\xc2\xd3\x53\x72\xf3\x26\xe5\x23\xc6\x6e\xd9\x73\x6b\x55\x8b\x5c\x66\x58\xca\x19\x03\x24\xac\x0a\x59\xf0\x02\xcb\xcd\x96\x2b\xe6\xa6\x03\x77\x1f\x52\x07\x3e\xe3\x26\xb9\x13\x9b\x69\xe1\x5d\x53\x72\x04\xd7\x99\x28\x73\x74\xb8\xe4\x18\x47\xa1\xea\x5c\x96\xbc\x60\xb2\xcc\xc5\x47\x30\xfc\x62\x46\xb3\xa6\x4a\xa2\xb3\x1c\x20\x3b\x6a\x02\x09\xef\x6a\xe8\xa3\x5c\x3d\x94\x53\x4f\x8a\xa6\x42\x3b\xbe\x86\xdf\x5d\x5b\x5d\x7b\x06\xa5\x89\x53\x65\x6b\xbb\xe1\xca\xd0\xb7\x28\x9e\x8b\xdd\xcc\x3d\x39\x50\xf8\x50\x59\xef\x27\x80\xa7\x10\x3e\x7f\xf9\x81\xf1\x01\x64\xa7\x9d\x40\x10\x7d\xf0\x0e\x0e\x2f\xee\x25\xe4\xeb\x45\x78\x6f\x2b\x4c\x89\x0d\x9a\x48\x96\xb1\x26\x0d\x45\xc2\xdd\x2a\xd8\x4c\x19\xa7\x19\x53\xd4\x17\xc4\xf9\x41\x5f\x12\xae\xa3\xd0\x02\x2c\x9f\xfc\x2f\xcc\x25\x84\x78\x1d\x44\x73\xb6\x62\x9c\xbd\x51\xb9\xe8\x53\x35\xa8\x38\x9e\x1e\xb7\x43\xf4\x8f\x3b\x61\xea\x13\xaa\x1e\xaf\x72\xc0\x66\x7b\x50\xf5\x1d\x66\xcf\xf2\xc2\x9e\x09\x67\x1e\xb7\x91\x27\xcf\xbe\x79\x4d\xd9\x1b\xf1\x10\xc7\xcf\xf7\xcd\xdd\x1b\x67\x84\x09\x62\x80\xbe\xcd\x29\xfb\x6b\xed\xa2\xf1\xfc\xef\xed\xd5\x1e\x72\xdc\x2a\x50\x06\x0f\x6a\x1a\x3f\xf7\xfa\x29\xd8\x73\xdc\x40\x4a\xae\x2f\x83\x3f\xd6\x03\x35\x7a\x11\x93\x77\x9d\xae\xe1\x60\x1b\xbe\xe6\xb5\x91\x6b\x9d\xa3\x47\x60\x6e\x25\x6a\xcb\x3a\x96\xf1\x92\xd7\x2b\x1f\x64\x02\x4d\x7c\x16\x70\xf3\x95\x5e\x04\x60\x40\xa5\x58\x56\x05\x34\x21\x54\x79\x2b\x42\x71\xb4\x06\x38\x6b\xdf\xae\xfb\x7b\xf7\x3e\x73\x02\x09\x03\xae\xdb\xa5\x30\xe4\x1c\x82\x30\x57\x8b\xb7\xec\x62\xac\x1a\xa3\xa7\xec\xf5\x9c\x8c\xfe\x28\x13\xe4\x61\x21\xe1\x6a\x29\x9d\x97\x3b\x6f\xc3\xc6\xaa\x6e\x6b\xa1\xf5\xa4\xab\xb0\x6a\xa1\x8d\xbb\x02\x71\x67\x09\xe8\xb0\x2d\x55\xc1\x7d\x54\xa8\xc7\xd7\x25\xa4\xec\x6f\xd9\x9c\x64\x63\x49\x64\xf2\x31\x84\xb0\x2d\x6a\xb0\x31\xa8\xa2\x80\xa0\xc5\x35\x92\xb7\x8f\xad\x3a\x20\x84\x76\xbf\xc1\x00\x2d\xac\xbc\x4a\x01\x9c\xe8\x28\x41\x17\x66\x09\x6a\x82\x43\xda\x82\xdf\x80\x40\x2c\x3c\x96\x74\xc9\x86\x47\x8c\x54\xf8\x75\x2b\x11\x5e\x96\xb9\x9d\x0e\x15\x87\xc6\xe8\x55\x77\x95\x0e\x84\x40\x0c\xdd\x4f\x20\xdb\xe0\x72\x77\x63\x49\xe7\x6e\xc8\x5d\x06\xa6\x0b\x21\xaf\x6a\xa9\x6a\xe6\xae\xa9\x7b\xc4\x3a\x17\x46\x64\x96\x1c\x52\x63\xf9\x59\x1f\x77\x26\x4b\x6d\x04\xcf\x5d\x9a\xaf\x8f\x23\x44\x17\x51\xed\x91\xd9\x5e\xc6\xd1\xa6\x38\x91\x9c\x5f\x89\x9a\x42\xa9\xc5\x8d\xbc\xb5\x07\x70\x57\x17\x01\x1b\x0f\x77\x24\xbd\x31\x8b\x5f\xe3\xaf\x34\x5b\xdb\x60\xb9\x75\xdb\x8b\x49\xe7\x37\xef\xe0\x23\x55\x89\x7a\x94\x98\x9e\xe1\x41\x34\x1a\x74\x8a\xcb\x0b\xc0\x60\x7b\xe6\xd0\x4d\xd6\xf7\xce\xbe\xe0\x95\x84\x0b\xe2\x4c\xdd\x8b\x9a\x42\x08\x55\xd6\xc0\x35\xeb\x10\xc8\x8b\xfb\x67\x01\xea\x85\x8b\x8c\x0d\xd0\x13\xe0\x17\x3d\x00\x5c\xa4\x22\x0e\xba\x66\x40\x24\xb7\xab\xb0\x32\x59\xf3\xcc\x72\xb1\x56\xf7\xbc\x08\xc9\x12\x6b\x5e\xa6\x0a\x55\xbe\x5e\xc5\x36\xc8\x5f\xdc\x3f\xdb\x11\xff\x60\x4a\x2c\x1b\x7b\xc8\x26\x45\x82\xe6\x0b\xe2\x7d\x6b\x75\x69\x21\xb5\x99\xb8\x60\x70\x97\x94\x52\xe1\x9f\x71\xcc\x3f\xfe\x3b\x6a\x54\xb7\x61\x7c\x4f\xa3\x34\xa0\x3c\x41\x06\x10\x48\xc6\xdc\x08\x35\x52\x46\xa3\x61\x9e\x8d\x89\x7b\x6e\xcc\x22\x65\x40\x27\x75\x15\x1d\x63\x3c\xc3\xc2\x03\x46\xdd\x89\x52\x83\xea\x65\x4b\xf8\x05\x23\x00\x48\x05\xf7\xaf\x53\x02\xf2\x22\xa3\xb2\x26\xce\x87\x0f\xb1\x0f\xf6\x7b\x7b\xa8\x6c\xa0\xcf\xb5\x95\x79\x18\x03\xb5\x3b\x8c\xb0\x45\x40\xb9\x43\x97\x86\x62\x77\x62\x85\x8e\x61\x80\x04\xb5\x1f\x8c\x0a\x97\x66\x65\xb1\x0a\x07\xe0\x17\x8d\x51\x3f\xda\xd7\x08\xc8\x7b\x40\x43\xa2\xb2\xa4\x0e\x48\x73\x5e\x68\x31\x65\x3f\xa3\x43\x11\xd3\x0a\xac\x31\xf3\x80\x86\xb7\xb0\xb6\x8e\xd2\x6c\x21\x6a\x2a\x75\xf2\xcc\x27\x98\x5f\xab\x7c\x82\xf7\x30\x95\xc8\xa0\xc7\xdc\x0b\x37\xc3\x94\x3e\x38\x2e\x0d\x58\xca\x82\xf1\xcf\xdd\xbc\x10\xcf\x2c\xd4\x56\xf1\x06\x09\x24\xd8\x4e\xd8\xec\xf3\x0e\x09\xec\x96\xe1\xb2\x97\xa0\xfc\xc5\xba\x61\x29\x48\x17\x93\x3f\x6b\x0b\x31\x3b\x20\x44\xa0\x1e\x7b\xbe\x27\x49\x2c\x5e\xa8\x80\xba\xa8\x8d\xa7\x49\x84\x3e\x7c\x74\x08\xaa\xec\x0a\x13\xe9\xf2\xc5\x9e\x74\x01\x28\xbf\x45\xc2\xbc\x5f\x44\x57\x9e\xfe\x52\x93\x36\x11\xd7\x5b\x0c\x76\x17\x2a\xfe\x04\xaa\x20\xaa\x2b\x09\x70\xff\xa9\x8a\x66\x49\x2d\x4c\xb9\x59\x80\x14\x7b\x2d\x26\x22\x65\xb0\x05\xe5\x49\x33\x38\x7b\x0e\xd1\xb5\xdb\x46\xfa\xb2\xcb\x06\x1b\x0b\xcf\xf5\x79\x06\x78\x13\x34\xfb\x7c\x5e\x3b\xb4\x8b\xe0\x5a\x68\xf6\x8c\x4f\x9e\xcd\x26\xcf\xf9\xe4\xf9\x0c\x06\x7d\x9e\x4d\xd9\xeb\x92\x8c\xce\xf0\x56\x36\xf9\x82\x4f\xbe\x98\xf9\x3d\xfb\x8b\x6c\x80\x36\x69\x43\x9e\x88\x36\x63\x0c\x3c\xbb\x91\xd0\x2d\xca\x07\xda\x2c\x06\x37\x13\x47\x96\xf7\xb8\x99\xfc\x68\x37\x32\xaf\x7d\xb7\xdd\x45\x70\x8f\xa0\x4c\x22\xdc\x3a\x40\xc9\x83\x54\x1c\x65\xeb\x88\xae\xdf\x7d\x39\x3a\x57\x73\x03\x9b\xf6\x66\x41\x5a\xe1\xea\x0c\xee\x81\x6b\xc1\xf3\xce\x28\x80\xf0\x84\xd5\x4a\x19\x76\xf5\x82\x4c\x8e\x60\x7f\x87\xab\x90\xb8\x1f\x6f\xc8\x69\x73\x2b\xda\xce\x1d\x45\x08\x68\x08\x12\x3e\x65\x2f\x8a\x82\x96\x08\xa0\x85\x32\x25\x8b\xd4\x16\x73\x85\xc7\xda\x98\x2d\x3d\xa0\xe0\x74\x89\xd7\x0b\x12\x03\x2d\x69\x4f\x90\xc3\x0a\x8a\x43\xa5\x90\x73\x81\xcd\x84\x0d\x16\xcd\xdc\x4a\x40\xf0\xc6\x10\x6f\xf3\x5c\x89\x61\x84\x06\x09\xa1\xe9\x57\x23\x7c\x24\xa8\xa4\x75\xe7\x53\x77\x29\x1a\x57\xb0\x08\xa4\xcb\x73\x91\xdb\xb3\x9b\x5e\xa8\x07\x9f\x08\x8e\x59\x8b\x90\x24\x38\x65\xd7\xee\x9a\x3c\xe2\x86\x03\x1d\x97\x5c\x80\x32\x19\xf6\x74\x87\xf5\x5d\xcc\xca\x97\xf7\xf0\xd7\x99\x6d\x4a\xc4\x9f\x7b\xf5\xd0\x87\x3d\xc0\xa6\x76\x6e\x49\xd1\x8e\xce\xcb\xf6\xd0\x1f\x22\xed\xdc\x15\x2d\xe6\x04\xf2\xe0\xcb\x89\x26\x38\xd6\x1c\xdd\x24\x1c\xff\xdd\xcc\x44\x66\x8a\x09\xbb\xb5\xb6\xf1\x4c\xa9\x3b\xc6\xab\xb8\x15\x79\x5b\x3a\xb2\x42\xfe\xea\xbe\x62\x59\x21\x45\x69\xd8\xdf\xfa\xbe\x6d\x97\xe1\xa5\x2c\x20\xba\x1c\x75\xfe\xd5\xf8\x83\x71\xae\xd5\xfe\xc1\xd2\x62\x3d\xbc\x64\xfc\xb6\x5c\x28\x6d\x58\x55\xcb\x25\xaf\x57\x94\x16\x89\x87\x96\xe7\xfe\xa9\x73\x79\x4e\xac\x16\x28\x0d\x44\xf3\x04\xa8\xd1\xaf\xee\x4e\x1b\x42\x87\x52\xd0\xb4\xc7\x76\x9f\x87\x30\x7e\x2a\xec\xfc\x93\xa6\xfa\x09\x09\xcc\x49\x90\x22\x90\x04\xc8\x5f\x75\x59\xb9\xa2\x34\xf5\x2a\x68\xcb\x5e\x2e\x51\xca\x3b\x7c\x1c\x3c\x76\xad\x2f\xa9\xba\x09\xc2\x25\x04\xe1\xe5\x29\x7b\x11\x81\x9a\xdb\x53\x04\x08\x9f\xe5\x90\x5d\x63\xbe\x54\xa1\xd3\x6d\x50\x02\xc5\x22\x69\x44\xda\x4a\x27\xb4\x9d\x83\xd2\x00\x7c\xcc\x56\x77\x87\x92\xe4\xfe\x77\x50\x3c\xf1\x5a\xdf\x1d\xdd\xe1\x44\x3b\x46\x32\xdd\x9f\xbc\x92\xe7\x3e\xb5\xd5\x09\x26\x80\x94\x73\x76\x0f\xfd\xb2\x25\xdd\xdb\xfb\x49\xf0\x4a\x86\x74\xd8\x4d\xf1\x18\x4d\xc9\x68\x0a\x76\xf2\xb7\xc2\x24\x9f\x4f\xec\x89\xac\x72\x85\xee\x48\x4c\x49\x87\x88\xdc\xbf\x16\xa2\x41\xce\xee\x9f\x9d\x51\x8d\x9e\x43\x12\x11\xbd\x38\x4c\x96\x73\xb5\x25\x01\xe9\xd3\x73\xfb\x69\x87\x80\x21\x74\x9f\xc2\x18\x61\x14\xdf\xe3\x33\x18\x5c\x50\x2e\x30\x01\xb5\x69\xcd\xf3\xa2\x68\x13\x36\xfe\xbe\x9f\xb0\xf1\x1b\x51\xb5\x1f\x92\xe1\x28\xd1\xe0\x47\xc4\x94\x82\xf9\x66\xc2\xc7\xf8\x1d\x8e\xe6\x38\x9d\x19\xa6\xe4\xa9\x1a\xdb\x1f\x6f\x43\x79\x0f\xa0\x4d\xf5\xbb\xd6\x0b\x68\x8d\xd7\x12\x13\xf6\x0b\x71\xcf\xa1\xd0\x4c\x28\x7f\x34\x87\xe1\xf1\xee\x60\x84\x3d\x87\xb9\x16\xb1\x2e\x8d\x72\x22\xb1\x22\x6b\xd0\x24\x4e\xc5\xb5\xb1\x0e\x99\x07\x44\xe4\x68\xe3\xb4\x14\x98\x04\xab\x6c\x42\xa1\x65\x13\x4a\xcd\x80\x7a\x2e\x10\xd2\x17\x4f\x82\xa3\x8c\x39\xad\xd4\x1d\x91\xa9\x92\xd5\xd9\x24\x68\xd7\x52\xe5\x08\x2c\xd8\x7f\x84\x0b\x74\xec\xf6\xa5\xa6\x98\x2b\xf2\x17\x0d\x77\x48\x41\x90\xf3\x79\x9a\xc1\xb3\x95\x14\xd8\xaf\x07\x25\xc0\x3e\xb4\xc6\x02\x25\xdc\xc1\x0f\x18\x1c\x07\x4c\x7f\x19\x35\x1f\x1f\x79\x7d\xd9\x4a\xa6\x63\x0b\x63\x2a\x1f\x0d\xf6\x12\x8b\xf8\xe1\x35\x24\x5f\xf6\xa7\xde\x05\x2c\x0c\x7e\x37\x61\xb3\x46\xaf\x66\xea\xe3\x94\xbd\xb4\x08\xab\x39\x2b\xe4\x7d\xe7\x63\x57\x22\x30\x8f\x1f\xf8\x6d\x26\xae\x48\x16\xcd\x92\x1a\x7b\x23\x40\xb4\xfb\x09\x08\xa2\x3c\xc2\x5c\x1a\xad\x44\x5d\x35\x3d\x12\xaf\xfe\x36\x4e\x5b\xb2\x57\x7c\xac\x94\x16\x2d\x93\xc9\x2b\x50\x5a\xb8\x63\x79\x07\x85\x4e\xe9\x5c\xef\x16\x68\x14\x8b\x67\x4f\x73\xb5\x61\x5f\x7f\xf1\xcd\x9f\x9d\x49\x42\x73\x76\x2b\x4b\xb9\xbe\x77\x2d\x1b\xaa\x7f\xaa\x9a\x41\x59\xab\xda\xb0\x67\xcf\xbf\xf8\x72\xca\xfe\xc9\x0b\x49\x11\x9b\x51\x10\xf5\x40\xbf\x76\xa9\x23\xd4\xa0\x48\x03\xc1\xf1\xe6\x86\xe1\xb5\xd5\xfa\xf0\x40\xea\xd8\x43\x60\x67\x30\x61\x74\xb7\xc5\x4d\x07\xdd\x18\x76\x6b\xa6\x3d\xb3\x74\xea\x13\x3e\x85\x7b\x21\x6f\xd3\xd1\xe8\xcf\xbf\xf8\xf2\x2b\x74\x2e\xbb\x27\xee\x40\xd2\x9d\x82\x7d\xd7\x3b\x09\xfa\xa7\xb1\xf5\x14\x0e\xa7\x8b\x30\x0c\xb7\x19\xba\xfa\x5c\x27\xa9\x14\xc1\x9b\x64\x9b\xfb\xb0\x60\xbc\xff\xf2\x4e\xf5\x0d\x02\x4b\x19\xf9\x69\x78\x7d\x68\x35\x4d\x87\x3e\xaa\x06\x7a\x17\x8f\x7f\x06\xc1\x95\xbc\xcc\x43\x11\xc4\x22\x39\x21\xba\x08\x0b\x59\x86\x58\xf1\x17\x01\x08\x72\x22\x3f\x43\x85\x73\x5e\x90\xdf\x9d\xf2\x5e\x63\x27\x84\x0b\xaa\x6d\x3b\xc3\x70\x38\x5f\x5c\x85\xe7\x60\x60\x5b\x29\x13\x2d\x5c\xf1\xbf\xcf\xcf\x9c\xd4\x62\xb7\xf3\x00\x64\xba\x19\x2d\xda\xae\x4a\x85\xeb\x98\x9c\x15\x70\x28\x04\xa8\x38\x0e\xf5\xf1\xc4\x3f\x2c\x41\xb1\xad\xfa\x21\xc5\x46\xdd\xf6\xc5\xb1\xaf\x15\x17\x75\xdb\x5f\x19\x10\xcb\xd1\xf8\x1e\xac\x73\x59\x58\x4b\x0c\x5e\xdf\x45\x6c\x30\xc9\xc0\x35\xef\xbc\x15\xa5\xa8\xad\x10\x59\x78\x10\xfd\x52\xd3\x45\xae\xfd\x2a\x2a\x03\x49\x31\x36\xfe\x8c\x53\xa8\x5b\x56\xc8\xd2\x1e\x8a\xac\x6d\x60\xff\x24\x49\x23\x5e\xe8\x35\x87\x23\x67\x81\xe4\x74\x20\x2a\xd4\x43\xc4\x5c\x98\xda\xb9\xe1\xb2\xf8\xee\xd9\x99\x23\x89\x47\x94\x3b\x43\x96\x92\x18\x2d\x12\x93\x50\xa6\xd0\xfe\xe9\xfc\x1c\xf0\xa3\xba\x8d\x40\x9f\x9f\x43\x49\xef\xf3\xd9\xca\x08\xdd\x0f\x9d\x92\x5d\xec\x1b\x34\x52\xf8\x1e\x00\x9f\x13\x6a\xf6\x1f\x72\x29\xb4\xe1\xcb\xaa\x03\xc7\x61\x46\x81\xe2\xfe\x3d\x59\xb2\x77\xdf\x5f\x7d\xf1\xc5\x17\x7f\x66\x68\x3a\x01\xc8\x08\x3f\x2d\xcb\x4c\x7c\xf7\x4c\x7b\xd4\x68\xb6\x40\x14\xd4\x7c\xb5\x40\xaf\xf1\x33\xa6\xa1\xd2\x39\x53\x45\x2e\x6a\xf4\xce\x95\xea\xa1\x1f\xe2\xf3\x2f\x17\xa3\x40\xe6\x7c\xd5\x85\x77\xa0\x55\x51\xb9\xa2\xfe\xbc\x2c\x95\xd9\x5e\xa3\xe2\xf7\x3e\x15\x27\x77\x70\x7c\x71\x3b\x9f\xe9\x61\xcf\x8c\x1b\xcd\x00\x10\xf6\xce\xfe\x8f\x29\x4f\x43\x2d\x27\x7d\x72\x07\xc6\xce\xba\xdc\x00\xd2\xc7\xa9\x02\x06\x74\xbd\x02\x6e\x23\x8c\xfb\x63\xf8\x21\xe9\xae\x81\x7e\x3b\xbb\xfc\x09\x3b\x9f\x93\x18\x4e\x60\xb1\xff\xc0\x39\xfa\x62\x7a\x58\xf6\x61\x29\xb3\x79\x9c\xa0\x15\x14\x41\x53\xe6\xa2\x5e\x63\x72\x1c\x50\x1f\x52\x84\xcc\x96\xfc\x76\x71\x35\xe9\x1e\xea\x96\xe8\xb9\xdf\x78\xdc\xd1\xe9\xec\x4c\x8f\xcc\x7a\x23\x96\x78\x56\xd1\x48\x67\xb8\x2d\xfb\x98\x14\x9f\x17\x82\x71\x2d\x50\x22\x06\xd8\x14\x65\xbf\x5b\xfa\x51\xc6\x0a\x46\xde\x84\xfd\x30\xbd\x32\x72\x7b\xeb\xf9\xdc\xed\x56\x46\x75\x31\x40\xb7\x27\x32\x79\xae\xac\x6d\x00\x2c\x3e\x27\x4b\x17\xb9\xe5\x82\x24\xdf\x53\x9d\xe3\x28\xcf\xce\x57\xea\x4e\xa9\x03\xb3\xb0\xaf\x86\xd4\x23\x8f\xf8\x21\xf9\xdc\x94\x03\x6d\xdb\xd7\xf2\x19\xbf\xea\xb4\x23\xb3\xbf\x61\x79\x53\x72\x5d\x03\x99\xe1\xb2\xcc\x15\xcc\x95\x9a\xbd\x11\xf7\xa2\xde\x9e\xe3\x4d\x79\xd6\xca\x02\xaa\x54\x3e\x71\x05\x24\x70\x28\x3b\x01\xb0\x41\x5d\xa7\x89\x78\x67\xb1\x58\x3b\xe3\x8a\x72\x98\x5b\x3f\xdb\xbf\x6b\x11\x2f\x59\x98\x12\xa8\x5c\x9a\x2b\x88\x5a\xe0\x90\xdd\x36\xba\xf2\x03\xa7\x47\xdf\xec\xe2\xd0\x3c\x43\x7f\xef\xb9\x96\xb9\x60\x79\xbd\x3a\xb7\x13\xe8\x0f\x1e\x5f\xc7\xc3\x3e\x28\xad\x53\x38\x4c\xd3\xd1\xdf\x1a\x84\xee\x3d\x5a\xd8\xd7\x9b\xf3\x9c\x21\x5e\xa5\x97\x95\x10\x96\x92\x75\x7a\x84\xf4\x90\xce\xdf\x70\x11\xd7\x26\xb4\x5c\xfa\x55\x02\x3b\x3f\x27\x34\xbf\xc3\x29\x9e\x75\x4d\x7a\x9f\x3f\xe9\x87\xb4\x2b\x2d\x12\x21\x4e\x3e\xec\x36\x81\x44\x69\x95\x38\x65\x67\x46\xef\xdb\xc9\x50\x36\xb8\xa1\x15\x7b\xc8\x83\xf9\x70\x01\xc6\x75\x1c\x6e\x95\x61\x24\xae\x6a\xa8\x46\x09\x9e\x6e\xda\x0e\xc1\xb1\x26\xf2\x4d\x2b\xb2\x97\x95\x34\xc6\x59\xe7\xea\x08\x2a\x30\x4e\x5a\xa5\x17\x27\x8c\xfd\x4d\x1a\xbb\xb4\xa5\xc1\xfb\x0a\x61\x32\xa7\x86\xaf\x10\xfb\xf8\x9e\xd1\xd5\x34\x86\x66\x04\x34\x62\x1a\x26\x00\xa9\x50\x65\x09\x51\x8f\xea\x80\x6b\xac\xaa\xd5\xc7\x15\xd3\x2a\xbb\xeb\x6d\xf5\xdb\x47\xf6\x6b\xfc\x04\xd1\x6e\x55\x8d\x39\x3f\x6f\x4a\xf9\xf1\x1c\xe1\x7d\x77\x01\xb7\xa5\xa3\x8c\x1d\xee\x30\x41\xb0\xaa\x64\xb3\x95\x57\x33\xc1\x70\xb1\xef\xb8\xb3\x55\x32\xd4\xff\x4f\xab\x28\x98\xe1\xff\x3f\x45\xb7\x33\xe5\x41\x06\xb8\x16\x28\xc6\x90\xe1\xcd\x55\x74\x3d\x00\xfa\x1c\x9c\x64\xdf\x5e\x5c\x14\x2a\xe3\xd6\xe8\xfa\xf6\xf2\x82\x57\x32\x1c\x51\x13\x60\x98\xc7\x83\x69\x96\x8c\x1b\x66\x19\x62\x40\x53\x7a\x89\x34\x35\x5e\x43\x1e\x94\x5b\x40\xe9\xff\x15\xf5\xd8\x0b\x80\x75\x0c\x43\x88\x44\x50\x1f\x0a\x7a\xb9\x2b\xd3\x3c\x6a\x23\xd8\x67\xdf\xfd\xee\x92\x7a\x28\xed\xc4\x2d\x2b\x00\x24\xbb\xd3\x0e\x7b\x42\xa4\xf2\x08\x16\x1d\xd8\xa2\xdc\xd9\x99\x48\x51\xdd\x2f\xc5\x52\x0d\x5c\xbe\xa6\x47\x00\xef\xe7\x20\x5f\xdc\x36\xfe\x45\x3c\x4f\x84\x4d\x9d\xec\xc9\x5b\xe8\x73\x41\x6e\xe2\x2b\xa7\x81\xd6\x0d\x8a\xa7\x01\xf6\x3c\x64\x9f\xb4\xca\x0d\x05\x73\x53\x1b\x0e\xed\x5f\x42\xce\x79\xf0\x0b\x47\x1d\x32\xc2\x97\x04\x11\x9c\x6d\x54\xd2\x6c\xc0\x0d\x89\x37\xa8\x52\xb3\xe7\x87\x34\x41\x20\xc9\xe6\xd0\x2c\x75\xc5\xc2\x06\x66\xf2\x3b\x13\x2d\x13\x43\x5a\x47\xe2\x7d\x26\xaf\xeb\xb3\x29\x7b\x33\x1e\x35\x6b\xe2\x3e\xdb\x00\xf1\xf9\xd6\x10\x0f\x20\x68\x6f\xc4\x03\x56\xc1\x8e\xdb\x7c\x52\x38\xce\x04\xde\x43\x9f\x17\xf8\x0c\xd5\x9c\xea\x67\xf7\x48\x9e\x45\xb4\x86\x88\x70\xa0\xe9\xaf\xae\xb6\x36\x94\x93\x6e\x95\xa7\x0a\xd1\xdb\x09\xc8\xd1\x72\x97\x22\x83\x56\x2a\x15\xf6\x0e\x71\x54\x28\x3e\x22\x54\xf8\x8e\xbd\x9d\x3e\x3c\xe6\xcd\xdb\xf7\x10\x01\xc4\x9a\x0a\x0f\x38\x45\xd4\x98\x07\x3f\x1e\x63\x5f\xb6\x66\x7f\x41\x5f\xee\x48\x6c\x72\xb4\x01\x90\xdd\x48\x2d\xd2\x9a\xde\x00\xc9\x79\x9a\xa1\x61\x90\xc8\x27\xce\x58\x81\x3f\x42\x09\x5b\x4b\x1a\xea\xec\x33\x8e\x1d\xa5\x2b\xc7\xee\xd9\xd0\xcf\x05\xe8\x8d\x4d\x91\x4c\xa8\x25\xd0\x90\x17\x0f\xd6\x98\x27\x4f\x25\xda\xce\x69\x67\x2d\x3a\x4e\xd8\x97\x5a\xe0\x3a\xd1\x4e\x6f\xde\xbe\x77\x69\x52\xa7\x61\xe9\xcb\x37\x37\x3e\x26\xa2\x87\x55\xa5\x30\x0f\xaa\xbe\xfb\xd5\xbe\xe7\x73\xb7\xc8\x1a\xb8\x10\x26\xbb\xb0\x36\x9e\x86\x38\x1b\x49\x97\x74\x40\x05\x0a\xb2\xf8\xe5\x07\x59\x36\x1f\xdf\x96\xc5\xea\xd7\x11\xeb\x23\x75\x6a\xc7\xa5\x73\xe0\xd4\xe7\x23\xdf\x42\x67\x1d\x55\xdc\x87\xc1\x72\x0a\x1e\x71\xc8\xb8\x4c\xe1\x3b\x1f\xeb\x30\xf5\xf1\xca\x92\x47\xe8\x77\xa8\xf9\x65\x97\x9a\x44\x88\x8b\xbc\xec\x27\xa1\x9d\xf9\xab\x8f\x46\xd4\x25\x2f\xde\xd8\x83\x1e\xc5\xb7\xf5\xa9\x9a\x75\x44\xb5\x3f\x75\x60\xf9\x4b\xd0\xd1\x9d\xe8\xa2\x52\x26\x22\x82\x34\x4d\xd4\x6f\x9b\x90\xee\xbc\xcb\xf3\xbc\x16\xda\x71\x13\x2e\xea\x10\x9e\x25\xdb\xd5\x9b\x17\x3f\xbe\x22\x6f\x69\x0c\x1a\xf5\x7b\xf4\x72\xc8\x4e\x9b\xf8\x53\xb4\x4b\xa9\xc4\xe1\x14\x96\x8d\x7f\x73\x43\x71\x5a\x4e\x7a\x7c\x20\xc5\x15\x79\xb4\xa2\xdb\x46\xb3\xaa\x44\x68\xa1\x94\x20\x60\x14\xa3\x14\xad\xd7\xd7\x93\xee\x70\x76\x1c\xdf\xa3\x0e\x81\xcd\xd0\xd4\xb5\x6b\xeb\x05\xab\x45\xa6\xea\xbc\x2b\x0c\x3d\x55\x40\x36\x09\x43\x44\x50\x66\x25\xcc\x3e\xda\x51\x0e\xc0\x3b\x6c\xff\xf1\x77\x82\xb3\xe5\x9a\xf2\x32\xb1\x10\x3c\x87\xca\x54\x89\x70\xd0\xed\x5b\xb7\x65\x21\xde\xa0\xb9\x94\xc2\x38\xbc\xcf\x55\x30\xa2\xd6\x7c\x6e\x7e\xae\xa0\x58\x33\xcb\xd5\x92\xbb\x3e\x1e\x3c\x8c\x57\x26\xf2\xe7\xe3\xe5\x5a\x32\x28\x8d\x66\x50\x5e\x91\x59\x3b\x08\x7d\x3b\x04\xb0\x24\x80\x0f\xa2\x80\x8b\x3e\x3f\x72\x60\xa3\x8b\x18\x74\xdc\xc4\x5e\x1c\xdc\xe0\xe0\x07\xe6\xac\x9f\xea\xbe\xac\xbd\xf1\x34\xfb\x8f\xe5\x65\x18\xea\x84\xcc\xd4\xfb\xa9\x68\xaf\x95\xc7\x6d\x6b\x1d\xa6\xb5\xf7\xb8\x76\x40\x45\x8b\x9c\x48\x0e\x3a\xe5\x53\xa3\x9f\x10\x93\x2b\xca\x1c\xba\xaa\xe9\xe8\x22\xab\x6f\x20\x5e\xae\xf0\x82\x2b\xdc\xf2\x03\x73\x43\x5c\x18\xb8\x5b\xfb\x77\x87\x58\x71\x5a\x4c\x5c\x37\x1b\x77\x01\xfc\xf2\xcd\x4d\x48\x32\x18\x61\xdb\x6f\x62\xd0\x6e\x76\x89\xe3\x4f\x6c\x88\x3c\x29\xcb\xe3\xe5\x9b\x9b\x03\x10\xe7\xfa\x1f\x2f\xdf\x24\x72\x38\x92\x4c\xf1\x7e\x88\xc5\x8a\x8d\xe4\x45\xb4\x44\x81\x7b\x6d\xc8\x2c\xde\x77\x36\xa5\x35\x0f\x2b\x2a\x08\x41\xb4\x1f\x16\x61\x97\xf7\xbd\x78\xfc\x82\x5a\xa7\x54\xba\xf8\x3a\x03\x42\xfa\x43\xa6\xac\xbb\xeb\x82\xcd\xa2\x20\xf5\x78\xc3\xc7\xbb\xd7\x77\xff\xf4\x06\x40\x3c\xd3\x6f\xd9\x0b\xcd\x7e\x96\x65\xae\x1e\x34\xa3\x0e\x53\xc5\x2a\xad\x22\xe3\x0b\x7e\x03\x86\x70\xb9\xf8\x8f\x97\x6f\x74\x37\x5d\xf6\x9b\x1d\x56\x40\xa3\x8d\x5a\x5a\x01\x43\x1f\xc4\x48\x1e\xfb\x2c\x65\x72\x5c\x00\x11\xad\x24\xdb\x77\x80\xbf\xd4\x33\x74\x0b\x47\x09\xec\x10\x2f\xdf\xdc\x50\x51\x2f\xae\xd9\x1b\x28\x88\x50\xe6\x0e\x4b\x0b\xdc\x8f\x88\xb9\x03\x78\x41\xb3\x72\xda\x3c\x1e\x1a\x6f\x4e\x78\x9d\x2d\x30\x27\x88\x58\x38\xae\x25\xbb\xab\xcd\x07\x50\x3b\xe3\x86\x10\xa8\xe0\xff\x8f\x6e\x6a\xf7\xe3\xcb\xeb\x12\x6a\x85\x0c\xd4\x11\xf0\xdc\x88\x5e\xeb\x70\xc5\xd5\x54\x88\xdf\x09\x45\x03\x46\x58\x75\x67\x74\x3f\x6c\x28\x85\x64\x5d\xd9\x80\xf1\x55\x03\x3a\xf0\xb6\xab\x19\xd0\xf9\x7c\x6d\xc6\xbd\xc4\xb9\x8b\x31\x09\xfd\x7d\x88\x6d\x09\xbc\x37\x7b\xbf\x9b\xb9\x0f\x50\xb7\xce\xde\xf7\xc3\xb5\x6b\x14\x84\xeb\x3e\x37\xb2\x8b\x74\x28\xa9\x09\xf3\x98\x9c\x7a\x27\x8c\x34\xcc\x80\x40\x62\x49\x8d\x71\x52\xe9\xdf\x65\x9b\x64\x13\xde\xc4\x2c\xf1\xed\x2a\x5b\x9c\x1f\x5c\x44\x07\x20\x1e\x4b\x48\xcf\x63\xd6\x66\x96\x0c\xb1\x38\x1d\x44\x54\xbb\x43\x8c\x96\x57\x0c\x2c\xd8\xbe\xda\xc4\x0e\xf2\x06\x88\x75\x5d\x81\x6e\x9e\x13\x26\x4b\x53\xe3\xc5\xfc\xc2\x98\x6a\x9d\xf8\x85\xaf\xd8\xdf\x6a\x5e\x42\x4f\xdb\xab\x85\xc8\xee\xf4\xb7\x18\x23\xe0\x1a\x01\x52\x29\x21\xac\x61\x6a\xc1\x9f\x57\x3e\x31\x76\xb9\x6c\x4a\xf2\x7c\x7f\x0b\x23\xee\xde\xb2\xdf\x1e\x78\xc4\x47\x91\x85\xe0\x0d\x6b\xfe\xf1\x0a\x4b\x2c\xce\xed\x8e\x5f\xa0\x9f\xc2\x64\x90\x5b\x07\x97\xda\xda\x1d\xb2\x28\xc6\x1f\xd2\xd6\xae\x1d\x04\x48\x41\x83\x1e\xfc\x9a\x71\xf6\x20\x66\x74\x17\x07\x29\x6f\xd6\x1e\xc1\xb8\x6b\x0c\xfd\xaa\x8d\x66\x7f\xba\xfc\xd3\x25\x1a\xac\x59\xe5\x9d\xbb\x7f\xba\xfc\xd3\x33\xf8\xb1\xc9\x2b\xaf\x9d\xdd\x0d\x24\xd9\x36\x55\xad\x3e\x4a\x91\xd4\x29\x66\xaa\x8c\x82\x22\xf0\x06\x01\x60\xaa\x39\xe4\x80\xd0\xa5\x44\x88\x00\x17\x99\xbb\x50\x08\x98\xb6\xc2\x7e\x6b\x08\x35\xe3\x48\x6a\x10\x47\xba\xfc\x00\xdb\x1f\xc3\xd0\x12\x9c\x56\x91\xd5\x45\x8b\xc3\x59\xca\xee\xce\x3e\xe9\xfc\x9d\x6c\xef\xd3\x34\x01\x18\xc9\xe9\x9a\x04\x00\x3f\x7c\x08\x8e\x22\xd4\xe2\x93\x09\xe0\x67\x4d\x15\x59\xb6\x62\x7b\x96\xfc\x23\xf5\x46\x84\x40\xd1\xe0\x73\xad\x85\xb6\x96\x39\x24\xa3\x41\x47\x1a\x08\xa0\x93\xff\x6e\x82\xf3\xa6\x7b\x98\x99\x6c\xe8\xf2\x1e\xe9\x81\x51\x2b\xa7\xc9\x4f\xbc\x70\x9a\xfc\xf7\x75\x73\x9a\x75\x63\x29\xfd\xfb\xb2\x39\xce\xb2\xb1\x3a\x69\xe2\xe2\x99\xf3\xb5\x4e\xd6\x9d\x96\x90\x05\xba\x7e\xeb\x89\x4f\xc5\xbf\x2f\xa7\x4f\x64\x1b\xc2\x70\x6e\x0f\x4b\x9b\x3f\x56\xb5\x32\x2a\x53\xc5\x77\x26\xab\x3e\x67\x3e\x25\x63\xc3\xa2\xdb\x7a\xc1\x25\x79\xf2\xbd\x8b\x6e\x97\x05\x87\x69\x1c\x7e\xd1\x45\xb5\xf9\xa4\x66\x4b\x5e\xdf\x89\x9c\x79\x39\x65\x90\x35\x00\xf7\x09\xb4\x24\x7c\x49\x2a\xb4\x36\x81\x7d\xc8\x2d\xc8\x3c\xad\x0a\x6e\xac\x10\x53\x19\x79\xf2\x86\x8c\xf0\x60\x7d\x82\x6b\x1a\x76\xc5\xdf\x97\xf4\x6f\x6b\x49\x37\xf9\xef\x4b\xfa\x54\x4b\x1a\x42\x25\x27\x94\xf2\xd6\xf2\xc1\xae\x5b\xc9\x18\x62\x19\x6a\x5b\x44\x4e\xfd\x8f\x2b\x5f\x6d\x87\xa7\x35\x46\x60\x71\x6d\x0a\xb4\x84\x3e\x2b\x70\xef\x01\x49\xf0\x2d\xb1\x31\x8a\xc9\xf2\x5e\xdd\x09\xc6\x2e\x00\x69\x87\x2c\x23\x89\x72\x1c\xbe\x00\x21\xbf\xa0\x00\xc9\xa8\x16\xb6\x2f\x9d\x64\x45\xbf\xa0\xf4\x56\x62\x98\x07\xe6\x04\x0d\xa4\xc6\xea\x80\x2d\x2e\x00\x60\xc8\xa1\xca\x57\x7e\x84\x82\x1b\x51\x66\xab\x09\x54\x66\xd2\x0b\x55\xf4\xb6\xdb\xf1\xf4\x6e\x7f\xaf\x1d\x00\x47\x78\xaa\xda\x05\x1e\x8b\x85\xbc\xdd\x18\x85\xfc\xae\x29\xd9\xb3\xcb\x4b\x26\x8d\x77\x11\xb9\xf2\xb1\x3d\xbd\x55\xe2\xf4\x6c\xb8\x65\xe1\x0d\x95\x9a\xa3\x34\xf9\xa5\xe0\xbe\xa5\x1f\x94\xdb\x95\x86\x19\x7e\x47\x17\x13\xde\x4b\x15\xdb\xb0\xce\x48\xf6\x24\xf1\x69\xf8\xf1\x5b\x2e\xf1\xc3\xd7\x38\x01\xbd\xa5\xa1\x0b\x26\xe1\x0d\x5a\x8f\x57\x06\xfc\xc6\x76\xb8\x74\x5e\xbe\x63\x0f\x4a\x52\xfa\x9d\xc6\xd5\x46\x8d\x37\xac\xe2\xf8\xea\xd2\x2c\x26\xec\xcf\x97\x66\x01\x18\xfe\xf9\xcf\x66\xc1\x2a\x51\x67\xa2\x34\x92\x46\xa7\x80\x29\xaf\x49\x44\xed\xb9\xe1\x2b\xa8\x61\x57\x13\x56\xc8\x99\xa8\xb1\x61\xaa\x30\x11\xaf\x2d\xb1\x9f\x5f\x22\x75\xec\x88\xd1\x10\x5e\xf3\x7f\x75\x19\x22\x74\xfe\x9c\xbe\xb3\x85\x38\xba\x6a\x4a\x84\xe1\x80\x60\x4e\x7c\x3a\xd2\xaa\x12\x93\x10\x98\x61\x29\x13\xc7\xb6\x8c\x90\xd1\xbe\xdc\xd9\x2c\x44\x86\xf8\x88\x90\x30\x88\x4b\x33\x4e\x82\x68\xb6\x8c\x9d\x51\x73\x84\xec\x81\x4e\xfd\x9a\x59\x73\x39\x81\xb7\x56\x2b\xc6\x35\x15\x5c\x4d\x67\x9e\x44\xb7\xb8\x02\xd4\xed\xc8\x96\xb5\xc4\x62\x78\x41\x6e\x40\xfa\x21\x16\x87\x82\x67\x20\x11\x37\x8e\xf4\x71\xd8\x92\xc7\xb9\xff\x22\x25\xd9\xbc\xbc\xac\x2d\xac\x81\xa1\xb5\xca\x24\xec\xfc\x3d\x24\x18\x0c\x21\x42\x7f\xea\xeb\x6b\x1f\x44\x04\x21\xe8\xa6\xa9\xcb\xf4\xd2\x0d\x02\xfc\xa0\xc6\x69\xb8\xa4\x86\x55\xeb\xca\x33\xb8\xe6\x4b\xc9\xa4\x46\x14\xe5\x6f\x89\xe9\x38\xf1\x7c\x35\x14\x47\x74\x48\xf1\xec\x70\x32\x1e\x68\x57\xf1\x8c\x81\x4e\x12\x0a\x3a\xc2\xc1\x75\x73\x6b\x6d\x24\x75\x19\x41\x54\x7d\xfd\xbd\x8e\x7c\xc6\xca\xb3\x33\x8f\x36\xb1\x18\xf2\x7b\xa9\xe0\x1e\x34\x79\x13\xc4\x74\x12\xad\x0c\xb0\x95\xfe\x74\x19\xc7\x95\xc0\x4f\x56\x55\xbd\xbf\xba\xb6\xbf\x3b\x13\x2e\x29\x19\xb7\x46\xa2\x47\xad\x3c\x6a\xf2\x16\x08\x11\xef\xcb\x4c\x45\x76\xf0\x1b\x17\x0b\x13\x40\xa9\x32\x88\x66\x8c\xf5\xc9\x44\xd3\x1e\x48\xae\x31\xcd\xe4\xa8\x92\xe9\xc6\xf9\x84\x05\xd3\x4d\x81\xaa\x8b\x8f\x11\xbc\x49\x47\xf2\xfc\x2b\xa9\xd4\xd1\xa5\x5e\x2c\x79\xfe\xf0\xe5\x49\x01\x91\xc5\x35\x1a\x9e\x67\x9a\xa1\xf8\x50\xbd\x7b\xd8\xc3\xfd\x14\x23\xae\x32\xc4\x23\x88\x9c\xd7\xb5\x11\x3d\x6a\xd5\x44\x5b\x87\xab\xea\xdd\xd5\xcf\x5e\xae\xd1\xf8\xef\x93\x6d\xcc\xa8\x8b\xe4\x9b\x5e\xb8\x06\x33\x36\x01\x08\xb5\xa2\xfa\xa1\x26\x53\x74\xb3\x39\xda\xa2\xf0\xc2\x79\x44\x6b\x22\x61\xc9\x81\x8c\x09\x4f\x98\x6d\x6c\x89\x43\xc8\x55\x4b\xa6\x12\xdd\x37\x46\xae\x7a\x96\xdc\x48\x4a\xed\x67\xae\xb4\x97\x19\x4c\x23\xb1\x53\x82\xe8\x46\x16\x4b\x48\x10\x0e\x2a\x7f\x12\xda\x1e\x02\x54\x4f\x9a\xb0\x56\x40\x52\xf3\x31\x56\xce\x90\x85\x83\x37\xe5\x4f\xc7\xca\xf1\x93\x0c\xf5\xde\x77\x5a\x20\x4e\xa0\x9d\x23\xcd\xe2\x9f\xb0\xdd\x4d\x70\xe4\xc2\xb0\x5a\xd6\xe3\xe6\xcb\x88\x81\x3a\x12\x50\x35\x14\x14\x8c\x84\x4e\x32\x58\x27\x80\xb2\xc1\x5c\x28\x39\x35\x38\xa0\xfc\xcc\x9e\x18\x3d\x0e\x32\x03\x42\xd0\x1e\xc8\xc7\x98\xd2\x71\xd0\x1f\x90\x9c\x53\x00\x17\x54\xfb\x7e\x04\xf1\x53\x25\xba\xbb\xce\x98\x2c\x69\x1f\xe3\x65\x60\x20\x7b\x7d\xad\x63\x2f\xd6\x31\x54\x61\xd0\x7e\xa0\x0c\xb5\xd0\xd8\x32\x66\x3e\x97\xa5\x25\x18\x6c\x7d\xe5\xae\xbc\xd6\x0f\x12\x6a\xb1\xb4\xa1\xce\x55\x9d\xae\x1b\xcf\xf2\x1d\x02\x03\xdb\x8a\xf1\x33\x07\xf5\xb3\x38\xbc\xab\x6b\x17\xf6\x1a\x84\x67\x67\xda\xa1\xfb\xc2\x61\x1b\xca\x8b\x7d\x86\xe9\xe2\xaf\xaf\x3f\xdb\xf1\x04\xc7\x2d\x08\x52\x32\x9f\xf5\xd9\x92\xa4\x57\xe2\x35\x01\xd5\x46\x28\x56\x17\xbd\xa3\x78\x3f\xb7\xa1\x89\xa9\xb5\x8e\xa2\xcc\xa7\x2f\xa8\x38\x4c\x2d\x42\x2d\x1b\x6a\xde\x8f\xa5\xd4\x5c\x99\xa5\x55\xaa\x99\x15\xb5\xdd\xf5\xf1\xdc\x14\xa8\x0b\xb5\x13\xb0\xc6\x06\x35\x37\x01\x97\x85\x28\x4d\xdb\xc6\x4a\xb0\x2d\xc9\x69\xa8\x72\x0c\x22\xbf\x0b\x3b\xc3\x08\xdb\xac\x87\x3b\x6e\xa3\xf8\xcc\x8a\xe9\x67\x23\x8e\xaa\x53\x17\xa1\x9b\x20\xbe\xe4\xb9\x88\xab\x86\x47\xfb\x23\xec\x8c\xb8\x35\x5a\x8a\x79\x4b\xb0\x3f\xc8\x1a\xa9\x15\x67\x6b\x84\x14\x13\x17\x30\x4d\x24\xa4\x94\x47\x42\x68\x68\x8a\x05\x08\x20\x4e\x07\xab\xa2\xa5\x92\x38\xe9\x9e\xbb\x07\x70\x60\xbe\xbe\x64\x17\x09\x70\xe6\x58\x29\xcb\x54\xa9\x45\xd6\x18\x49\x51\xe2\x23\xec\xc1\x1d\x6c\xc1\xe4\x0c\xd6\x6f\x0f\x46\xb6\x60\xd7\x18\x4c\xe3\x6a\xc9\xe7\x4c\x31\x5e\x22\x71\x57\x77\x94\xcf\x56\x61\x4b\x9b\xd4\x67\x74\x2e\x7c\x0c\xfd\x99\xfa\x42\xad\xf2\xcb\x82\x13\xe0\x10\xaa\x34\x28\xab\xe9\x7a\x0d\x49\xe8\xec\xa2\x25\x53\x0d\x19\x0d\xe9\x96\x76\x9a\xc7\xb5\xaf\xda\xf3\x3b\x74\xac\xfa\xf6\x53\x7b\x34\xf9\xae\xea\xdb\x43\xed\xb5\x9d\xcd\x7d\x64\xdf\x5e\xed\xd1\x5d\xe0\x90\xea\x0b\xe6\x93\x34\xa3\xd4\x9a\x55\x69\x98\x3b\xfb\xbb\x5a\x73\x6a\xad\x4f\x35\x9d\x46\x2d\x7d\x2f\xd3\x72\xdc\x6e\x6a\xd0\x21\x19\x73\x46\xde\xb8\xdc\x9c\x6d\x34\x12\xf5\x4d\x48\x1c\x24\x71\x22\xb1\x4f\xf8\x19\x13\x6f\xfe\x03\xf4\xf5\x28\x8a\x30\x8a\x44\xfb\xc6\xa3\xa6\x21\x37\xae\xb2\x1c\x73\xdd\x0d\xb1\x48\x31\x4f\x5a\x4d\xd9\x51\x93\xe9\xfa\x93\x9a\x87\x64\xa5\x81\x66\xde\x31\x9a\x7b\x02\x87\x0e\x68\x34\x3b\x39\x0e\x95\x1d\x55\xb3\x95\x9f\x0d\x32\xbe\xbb\x90\x11\x10\xd6\xcb\xfc\xf4\xad\x68\x4a\xdc\x18\x98\x64\xd8\x55\x76\xd8\x47\x3a\x96\xb6\x8e\x44\x67\x83\xa5\x4d\x31\x08\xa3\xb7\x1a\xd2\xd5\xe3\xac\xec\xb1\x5b\x8d\x57\xab\xe3\xac\xec\x31\x5b\x4d\xcf\x86\xba\xc6\xc0\x6d\xa9\xc6\x75\x86\xed\x96\x1a\x38\xcc\xa6\x29\x8d\x2c\x1c\xc3\xa9\xd2\x1a\x42\xc4\x9f\x26\xe1\x55\xcf\x70\x8b\x07\x55\xfc\x0b\x15\xd1\x81\xec\xed\x0d\x28\xc6\xdf\xe5\x80\xed\xa3\xde\xbb\x16\xeb\x00\xd4\x6d\xac\xd6\xce\xd6\x40\x42\xff\xc8\x56\xeb\x29\x15\xd8\x53\x37\x63\x37\xa9\xa9\xf5\x2a\xaa\xc7\xbd\xdf\x6b\xee\x6e\x6b\xea\xba\xd5\xbc\xe5\x29\x7f\xa3\xfe\x71\x91\x58\xdb\x9d\xf2\x77\xd4\x3f\xe3\x94\xcc\x3a\x05\x03\x40\xc7\x2b\x19\x26\x3e\x56\xb2\xb6\xea\x9d\x8a\x71\xf6\x2a\x1a\xb7\xae\x77\x54\x36\xeb\x15\x8d\xdf\x82\xd6\x2b\x9b\xad\xec\x48\x84\x79\x0c\x65\xb1\x85\xb1\xb3\xbf\x7a\x70\x6a\x61\xc0\x21\xfc\xa9\xd8\x35\x87\xf2\x0e\x8e\xf4\x0c\x26\xf6\x0a\x1d\xf1\x0e\xe6\x15\x74\xc9\xce\xdb\x1d\x8f\xf9\xd1\xfc\x82\xeb\x2c\x96\xae\x5b\xe9\x13\x39\x33\xfe\x87\xb8\xc2\x8e\xa0\x28\x62\xb3\xfe\xa9\xda\x0f\xbf\xbb\xc1\x76\x70\x83\xc5\x47\xfd\x43\x2e\xe5\xb0\x8c\xbb\x2b\x6f\xdf\xf3\x41\xbc\x14\x01\xfa\x49\xdd\x3f\x5d\xcf\xcf\x36\xeb\x2c\xec\x84\x59\x03\x5e\xc1\xb8\xe9\xdc\x26\xa7\xce\x5f\x57\xde\xc3\x44\xea\x3f\xd4\x2b\x09\x6d\xf2\x92\xee\x22\x75\x74\x71\x82\x55\x69\xf1\xf5\xb3\x64\xcb\x6f\x15\xc7\x27\x50\xdb\x87\x98\x0e\xaa\x2d\x1f\xb4\xbc\x0d\xad\x50\x14\x39\x9b\x71\x2d\xb3\x10\x24\x0c\xe2\x38\xa6\x15\x5c\x7f\x75\x35\x9e\x86\x1b\x5b\x63\x95\x97\x2b\x48\x3e\xe9\x56\xf5\xc1\x1d\xa9\x29\xf1\x6c\xb2\x50\x0f\x4c\x2c\x2b\xb3\x8a\x8b\xf7\xbc\xc8\x5d\x5c\x7b\xcf\x45\x63\xa7\x4a\xd0\x3d\xb5\x99\x72\xea\x06\x60\xba\x7b\xc7\x10\xda\xed\x82\x7e\x31\x2b\x04\xdb\x3e\x79\xbd\x81\xbd\x0b\xa0\x83\x05\xae\x74\xcc\x37\x11\xe1\x0e\xdb\x95\xab\xb4\x80\xaf\xdb\x20\x66\x2a\x84\x74\x87\x03\x3f\x20\x06\x38\xc3\x56\x90\xa9\x1a\xbd\x83\xb9\xd3\x62\x6e\x1a\x0e\xc9\x29\x7b\x5b\x66\xee\xde\x10\x5a\x9f\x50\x31\x1e\x57\x22\xd1\x2c\xa8\x31\xb9\x9a\x77\xc2\xea\x01\xa2\xa3\x45\xee\x09\x01\x7d\x4f\x70\xce\x5e\xe9\xcc\x65\xad\x4d\x94\x87\xe2\x9b\xa4\xd0\x94\x08\x0f\x3b\x2b\xe7\xcc\x49\xaa\x6f\xb6\x29\xeb\x95\x59\x4b\x25\x01\x63\x8f\x21\xf2\x28\x76\xcb\xa6\x30\xb2\x2a\x88\xa5\xdb\x2f\x03\xfc\xde\x2a\xb5\xd6\x5c\x76\x5f\x09\xe6\x41\x11\xb1\x67\x8d\x61\xa5\x42\x81\xb0\xa4\xf3\x2d\x4f\x22\x42\x01\x71\x57\xf6\x08\xde\x6d\x26\xd6\xb3\x42\x5a\x8c\xf7\x0b\xe5\x3a\x2c\x14\xe0\x2c\xf1\xac\x73\xd3\x8b\x22\x5c\x46\xc9\x01\x6e\x4d\x58\x08\xae\x77\x2e\x66\x6e\xb4\xd6\x42\xba\x95\x83\x68\x0e\x0d\xe0\xd7\x42\x84\xe7\x4b\x2c\x1a\x1b\x64\xcf\x81\xec\x5d\xd0\x84\x67\xb1\x4a\x33\x19\xd2\xe1\x61\xc5\x46\x70\xf1\x67\x17\x19\xd3\x01\x0c\x95\x24\x4a\xf5\x80\x4b\x71\x80\x9e\x7b\x4b\x2a\xd6\x27\xfa\x91\xbb\xd4\x3d\x51\xde\xcb\x5a\x95\xd0\xb9\x70\x2e\x45\xd1\xd7\x75\xc2\x5a\xc7\xbf\x86\x2f\xa3\xcb\x54\xbb\xf7\x37\x4b\xd8\xd2\xef\x25\x4f\x80\xdd\xf3\x5a\xc2\x83\x4e\x6e\xde\x88\x8b\x8c\x6e\x45\x23\xe8\x2f\xdc\x03\x1d\x7a\x55\x03\x9d\x5c\x66\x19\xfe\xe2\xfd\xa7\x1e\xed\x29\x7b\x11\xcd\x01\xdf\xf2\xbb\x24\x58\x8a\xd2\x02\x74\xbb\xa1\x57\x3d\xd1\xb0\xe3\x33\xaf\xb0\xa2\xd1\x92\x57\xdb\xd0\xdf\x4d\xaa\x57\x51\x8c\xe5\x01\x0a\x64\x00\x7a\x20\xf2\x27\x30\xe3\x94\xaa\x98\xbe\x45\x11\xfe\x74\xca\xbe\x11\x61\xbb\x89\x1a\x16\xeb\xfe\x99\x77\xc8\x7f\x58\x92\x63\xa5\x55\xbb\xb4\xce\xef\xc4\x6a\x3c\x99\xe7\x5c\x16\x51\x80\x5d\x78\x1e\x00\xb2\x3b\xb1\xda\x40\xd6\x17\xc6\xd8\x57\x93\x48\xbd\x16\x28\x2b\xe6\x0e\x1a\xc5\xce\xc5\xc7\x1a\x74\xc8\x71\x59\x8c\xa9\x85\x3b\x9a\x2e\xa1\x3a\xf4\x78\x8a\xc4\xcd\xf5\x79\x1f\xa8\x7d\x68\x41\x3d\xf1\x51\x12\x28\xaf\x35\x7a\xf8\xbd\xc0\x86\xf9\xde\xf2\x09\xc3\x53\xba\xe6\x1c\x92\x09\x31\x5e\x58\x4f\xad\x09\x3d\xa7\x6f\xbc\xd9\xe5\xbf\xd1\xb0\x6c\xa8\x85\x23\x19\x3d\xf6\x73\x55\xfb\x9b\x7a\xb8\xa4\x4d\x07\x9a\xad\xb0\x67\x3e\x35\xfd\xa7\xb6\x86\x65\xee\xaf\xdd\x41\xf4\x81\x85\xa9\x1a\xf2\x85\x1b\x9d\xa5\x32\x5b\xb1\xab\x50\xf8\x67\xc4\x51\x65\x13\x5f\x5f\xaa\x87\xf2\x81\xd7\xf9\x8b\xeb\xd7\x93\x54\xbf\xab\x9a\x5d\x5d\xff\x04\x68\x2e\xc5\x52\xb9\x44\x57\x2c\xf2\x16\x79\x92\xfb\x65\xc0\xc1\x8d\x6b\xa5\xb9\x93\x8d\x5f\xaf\xf6\xec\x8e\x40\xa7\x59\xd5\x5c\xe0\x30\x7e\x23\xf5\xe7\xc3\xf0\x8c\x54\x81\x55\x01\x7a\xeb\x3c\xee\x04\x25\xaa\xf5\x04\xcd\x52\xed\x34\x5d\xf6\x30\xa4\xf1\xe2\x58\xee\x27\x4a\xca\xb3\xd2\x0b\xb8\xf5\xeb\x22\x0e\xbd\xe9\x30\xad\x71\x67\xb5\x94\x13\x8a\x1f\x78\x25\xb7\xe2\x94\x3b\xf4\x1d\x89\x63\x0e\x7c\x87\x59\x61\xeb\xc4\x6e\xd4\xe8\x1b\xed\xdf\xca\x0f\xcc\x1e\x9a\xdb\xa7\xc0\x1d\xe8\x54\x28\x7b\x8b\x01\x6d\x24\x3d\x7c\x0b\x91\xf0\x64\xd6\xd8\x59\xed\xb4\x51\x0f\x12\xd8\x19\x98\x21\x4b\x1e\x8c\x3b\x3d\xb8\xf1\x92\xc7\x06\xeb\x40\xc6\x18\xf6\x5a\x5d\xa1\x4a\x23\x7c\x02\xc7\x87\x7b\x89\x06\x54\xe0\x0b\x26\x0a\x9f\x9e\x37\x16\xad\x9f\x5e\xbf\xdc\x89\x37\x15\x7e\xbb\x5e\x2b\xed\xcb\x19\x3b\x40\x24\xe4\x83\x46\x20\x7b\x64\x21\x2f\xd3\xae\xf7\x98\x91\xb7\x9b\xcc\x5b\xba\xf6\x81\x0b\x09\x1a\x94\xfd\x75\x84\xcd\x60\xcf\xc5\x60\x3f\x7f\x33\x80\xfa\xf8\xf5\x81\xf6\x70\x67\x8d\x1c\x89\xad\xd7\x2a\x7f\x2f\x96\x55\x01\x05\x07\x7b\x1a\xa2\x0c\xf2\x30\xfa\x50\x6f\x68\xa8\x02\xde\x2f\xff\xee\x06\x73\xcf\x1d\x65\x2d\x49\xc2\x00\xa1\x8a\xb3\x3b\x66\x50\xcf\x6e\x67\x81\x61\x9f\x9c\xf8\xda\x78\xae\x9a\x32\x0f\x0d\x37\x5c\xef\xbe\x21\xf0\x7d\xad\x3b\x5c\xdb\x0e\xbc\xd8\x08\x90\xd0\xa8\xd3\x2d\x1c\xb6\x30\xc9\x2a\x95\x7b\x82\xac\xe1\xc8\x08\x7b\xbb\x8f\x0d\x68\x72\x47\x5f\xd3\x84\xdf\x8f\xe5\x41\x8f\xc9\x1d\x7d\xde\x67\x74\x27\x8f\x3b\x66\x77\x3c\xa5\xf1\x86\x77\x82\xf1\x78\xd3\x3b\x1e\x6c\xa4\xf1\x0d\x10\xdf\xb7\xbe\x6d\x99\xdf\x07\xe2\xee\x0f\xd6\x72\x79\x67\x67\x3d\x09\x85\x72\x7b\xb8\xab\xb3\x85\xc8\x9b\x42\x96\xb7\xbf\x46\xdf\x74\xfa\xae\x46\x8f\x60\x5d\x90\xb1\xa6\xbd\x21\x4d\x17\x50\x50\x87\x09\x9a\xa9\x5b\x3d\xe7\xde\x62\xbc\xaa\x0a\x69\x57\xc6\x88\x63\x3e\x3a\x4d\x60\xc0\x1a\x06\xb4\xe0\xb1\x85\xbc\xab\xdc\xe1\x8f\xa0\x6a\x1e\xbd\x48\x05\x4d\x63\x81\x68\x43\x41\x57\xaf\x03\x13\x9e\x4e\xc3\xd0\xe0\x7d\x84\x39\x86\xfa\xc2\xae\xe0\x81\x73\x15\xfb\x6b\xb1\xe8\x95\x5a\xb8\x59\x3a\xaf\x5b\x00\x3f\x22\x1c\x35\xf0\xe1\x02\x8c\xce\x0f\x88\x57\xdb\xad\x8b\x6f\x89\x7a\x12\x77\x52\xb2\x36\xea\x06\xd6\xfa\x0f\xaf\x6b\x91\xcb\x0c\x17\xe7\x8d\xa8\x25\x2f\x7e\xf5\xd3\xd2\x3d\x40\x19\x29\xd6\xa8\x2d\xb8\x35\xc0\x1f\x7c\x2f\xea\x8d\x75\x74\x3c\x16\x91\xa7\x1f\xdc\x17\xd2\x5d\xdf\xd1\x98\xfe\x76\x90\x4a\x96\xfc\xc8\xed\x3a\x85\x92\x2a\x3c\x93\xa3\xbc\xe2\x11\x15\x2b\x3f\xd1\x35\x44\x84\x03\x85\x5f\xe2\xd0\xe6\x02\xc5\xe7\x00\xb4\x04\x7a\x59\x8b\xe1\x86\xe0\xa3\xf5\x09\x44\xa6\xbe\x07\x72\xee\xc7\xdc\x58\xb9\x3b\x34\x01\x03\xe5\x42\x79\x86\x30\x81\xff\xe7\xee\x5b\x76\xff\xff\xc2\xb6\x53\x26\x9a\xd4\xed\x61\x1d\x2c\xe8\xd6\xda\x7d\x08\xa5\xcf\xf0\x02\x58\x38\xb6\xd0\x35\x0a\x4d\xdc\xae\x5d\xdf\x1f\x22\x06\x87\x13\x20\xe3\x10\xee\x5a\xe2\xa4\x4a\xff\xb5\x77\x95\x5b\x84\x3b\xf7\x9f\x07\xe7\x64\xa9\xcc\xa3\x70\x33\x1e\x77\x17\x9f\x66\x42\x59\x62\x92\x73\x20\x03\x06\xfe\x6e\x39\xb4\x64\xe1\x7d\xf5\xa9\xa6\xec\x46\xd2\xbd\x98\x5d\xb1\xb5\x95\x14\x0c\x1d\x0a\xf8\xa1\x26\x95\xc6\xce\xd5\xb1\x3c\xdc\xc0\x53\x31\x85\xc0\xff\xc3\xf2\x0c\x6a\xf7\xfd\x5d\x69\xe3\xb2\xcc\xd9\x35\x05\x61\x21\x82\xf8\xf0\xf5\xb5\x8e\x42\xf1\x66\x0d\xde\xc5\x50\xe8\x85\x73\x18\xe0\x8b\xec\x8f\x97\x53\xf8\xff\xcf\x0f\xc8\x70\x24\x1f\x94\xeb\xc6\x31\x33\x55\xce\x0b\x99\x59\xd2\x98\x07\x21\x4a\x54\x8d\xc0\x3d\x08\x4b\x58\xc4\x33\x72\x61\x65\x1e\x71\xbc\x11\x20\x3c\xe1\x5d\x4a\xa9\x5f\x2f\x29\x61\x4b\xf2\xe1\x0f\xbd\x94\x9b\xc0\x40\x81\x5e\x44\xc1\x49\x30\x57\xc1\xd6\xa4\xf9\xfb\xcb\x21\x68\xe3\x02\x22\x34\x07\x2c\x21\xac\xc2\x6e\xdf\x96\xfa\x12\x53\xa1\x5b\xb4\x56\x73\x37\x0b\x2a\x28\x0e\x56\x71\x2d\xaa\x5a\x68\xec\x3b\x58\xb8\x8c\x66\x1f\xc4\x31\x26\x93\x79\x77\x09\xf2\x52\x6d\x09\x42\x58\x26\x52\x55\x2a\x73\x7e\x04\x95\x80\x12\x42\x12\x59\xaa\xf1\x02\x92\xb2\x6a\x11\x30\x76\x52\xb3\xa7\x60\xb4\xee\x93\x28\xc9\x30\xd1\xc9\x71\x0a\x6c\x2c\x04\x16\x98\x63\x74\x1d\x28\x28\xa3\xb5\x78\x30\x66\x5a\xe5\x57\xd5\xc2\x9e\x03\xa0\x80\x9f\xb5\xf3\x42\xa3\xd4\xb1\x5c\x72\x9f\x7b\x2e\x85\xdf\x5e\x41\x1d\x46\xa9\xca\x6b\x4e\x57\xf3\x75\x53\x6a\x17\x4a\x75\x23\x30\x1a\x09\xed\xcb\x18\x13\x17\x8c\x02\x3d\x46\xd6\xb3\xe1\x7b\xd5\xd4\xac\x10\xf7\xa2\xd0\x74\x02\x82\x6b\xa3\x78\x08\x34\x9a\x3d\xbb\xa3\x97\x6b\xa9\x6a\x69\x56\x13\x8a\x3a\xd4\xa6\x96\x19\x1d\xfd\xb0\x97\xec\xd5\xf5\x4f\xce\x0f\x89\x57\xbd\xbc\x29\xb3\xc5\xd4\x7f\xc9\x9e\xb1\x73\xf6\x45\x64\x5c\xe9\x8a\x3f\x94\xd1\xb5\xf6\x5c\x91\xc1\x36\x5b\x85\x8f\xbe\x0c\xc5\x10\x3a\x78\xbe\x73\x6d\x63\x01\x1c\x39\x02\xf0\x1e\x8f\x3a\x36\xa1\xb4\xfb\xa6\xad\xee\x83\x31\x67\x97\x54\x2a\x88\xda\x6b\x36\xf6\xbf\x42\xd8\x4d\xe0\xe7\x3e\x52\x11\xd6\x2e\x06\xf3\x54\x31\x54\x06\x71\x86\x9b\xce\xac\xae\x29\x97\xbc\x85\xe0\x36\x47\xce\x2a\xe9\x00\x45\xed\x8a\x70\x41\xe1\x8d\x5c\x09\x7e\xb5\xf8\x24\x06\xd6\x03\x38\x0f\x28\xe0\xc7\x61\xee\x7a\x67\x03\x6e\xd6\xe0\x53\x0f\xed\xa1\x20\xca\xc1\xeb\x71\xab\x60\x25\xb9\xa6\xe3\xd7\x8e\xc1\x8e\x88\xac\x58\x50\x51\x1a\x99\xf1\x82\x61\x5d\xdc\x03\x70\x26\x9d\xad\x4f\x8c\x8a\x56\xe6\x6c\x95\x0c\x3b\x8e\x61\xc9\x17\xdb\x70\xca\xe9\xf6\x1d\x39\x65\x8d\xea\x98\x51\x0e\x0f\x37\xb1\x83\xf1\x28\xdc\xe7\xfd\x53\x15\xcd\x12\xfa\xea\x7e\x34\x2c\xe7\x86\x4f\xd8\x4c\x96\xbc\x5e\xc1\x1f\x7d\x5c\x32\xaa\xe6\xb7\xc9\xa5\x6a\xf4\x41\x74\xb3\x4f\xee\x14\xec\x8a\x74\x0f\xc3\xec\xe4\x8b\x7e\x9f\xdc\x5c\xfa\x2a\xc7\xb1\xe3\xcd\x23\x0f\x1c\x8a\xd1\x89\x63\xb7\xa2\x30\x09\x2c\xad\x9b\x87\xc8\xaa\x52\x3c\x14\xab\xd8\x71\x14\x0a\xb3\x3a\xdc\x97\xaa\x29\x8d\x1f\x7f\xc9\xab\x4a\xf8\xb0\x1d\xea\x4d\x05\xea\x3f\xea\x01\x15\xf0\x3e\xd3\x9b\x91\xa4\xfd\x2c\x94\xdb\xb0\x28\x7a\xdb\x5b\x95\x46\xb8\x48\x42\xfb\x03\xa0\x23\x72\x60\xbf\x5e\xd7\x78\xea\xf9\xe6\x3b\xd8\x0f\x38\xc5\xcd\x52\xe2\x5a\xc4\x44\x0d\x86\xd0\x13\x35\x4e\x50\x14\xb0\x94\x17\xf4\xbd\x5e\x2f\x2d\x28\x1b\x5b\xba\xd1\xd7\x4b\x4b\x4f\xc4\x4c\xbf\x28\xa0\xfd\xbe\xad\x38\xac\x13\x85\x9f\xe3\x60\x47\xa4\xbc\xfd\x2a\xce\x75\x87\x27\x54\x25\x4c\xb5\xdf\x6b\x0b\x49\x24\x20\x31\xd8\x61\x21\x49\xb0\x79\x51\x68\x85\xce\x63\xfb\x93\x34\x62\xf9\x47\xfb\xce\xe7\x91\xd3\x19\x15\x99\x87\xe4\xa8\xd9\x2a\x29\xcd\x99\xa8\x6b\x55\x47\xb2\x6a\x09\xe2\xe1\xed\x10\x00\x33\x5a\x18\x5d\x28\xac\xa5\xfd\x80\x9d\xde\x15\xc1\xde\xc8\xa3\x10\x94\xb8\x9f\xaa\xba\xea\xc4\x82\x4c\x52\x17\x0b\x50\x07\x98\xa2\xed\x51\x1d\x47\x02\x3b\x5e\x55\x0d\xb8\x66\x3d\x2f\xe9\x21\xda\x82\xa0\x59\x8d\x8a\x5a\xcc\x45\x01\x25\x9b\x45\xde\xdd\x3e\x1c\x42\x03\xe2\x78\xb4\x39\x30\x2f\x72\x14\x5e\x0f\x82\x16\x45\xcc\xe7\x18\x2f\xe5\x9c\xb2\x92\x36\x51\x78\x6d\x09\x1e\x06\x78\x99\x4e\x8c\x4e\x9d\x5e\x7e\xfc\xfa\xcb\x2f\x4f\x28\x3a\x13\x56\xaa\xf2\xbc\x56\xca\xb0\x46\xf7\xb6\x02\xdd\x47\x92\xb8\xf6\xe0\x77\x52\x69\x8f\x23\x55\xe4\xd2\x83\x30\x59\x0d\x7e\xa3\x88\x42\xa1\xea\x75\x23\xf3\xef\x9e\x5d\x5e\x5e\x8e\x11\xc3\x43\x6a\x5e\x1c\x0f\xe4\x88\xdc\x06\xf4\x34\x74\xc5\xf7\x42\x16\x7b\x31\x7d\x8b\x54\x38\xf1\xaa\xf9\x23\xc8\x9a\x9f\x06\x38\x21\xfb\x52\xa7\xf7\x91\x36\xcf\x19\x9a\xe9\x8f\x34\xcc\x61\x3a\x4e\x9c\x54\x04\xbf\x77\x0c\x8c\xda\xbc\xa3\x93\x13\x37\xd9\x10\xa4\x69\x19\x79\x76\xf9\xf1\xcb\xcb\xcb\xb3\x3d\x05\xd1\xa3\xb9\xbd\x3e\x1c\xd4\x85\x51\x2d\x80\x91\xfa\x70\x26\x9c\xbc\xc2\xb6\x8e\x26\x45\x7b\xa6\x74\x41\xb8\xb9\x65\xc3\x9a\x5c\x23\xac\x99\x49\x4d\x24\x32\xdc\xf2\x2d\x2e\x95\xa8\x97\x12\x12\x91\xb6\x68\xd8\xb0\xdb\xda\x38\xd2\xfe\xed\xd7\x01\x81\xdf\x3e\x22\xe3\xf1\x84\xde\x95\x5f\x72\x36\x25\x8f\xcd\x49\x94\x7a\x24\xf0\xa3\x28\xdd\xb5\xb2\x1e\xcb\xb9\xbf\xef\x1d\xb3\xf7\x9f\x6c\xdf\x3f\xb9\x22\xf6\x02\x08\x61\x37\x46\x2c\xfd\x88\x9f\xa8\x4e\x1e\x2f\x9e\x9b\x34\xf8\x28\xed\xed\xdc\x5f\x5b\x4b\xf5\x5a\x89\x46\xd6\xec\x20\xd5\xeb\x24\x3a\xdc\x88\x8d\xd2\xe0\x63\xb4\xf7\xa6\x6c\xd1\x54\x83\x3f\x9a\xf6\x3e\xae\x09\xdd\xb3\x96\x82\x51\xfd\x9b\x5c\x39\x9b\xcd\xef\xb1\xa6\x77\x22\x93\x07\x39\x01\xfa\xc8\xa4\x71\xe6\xf7\xe3\x99\xde\x3e\x81\xd1\xa1\xcf\xab\xde\xd8\x97\x91\x92\x29\xcb\x36\x44\x1d\xb3\xce\xa7\x9a\x7f\x72\x3e\xab\x90\xe8\xc9\xcd\xa2\xed\x4c\x44\x56\x3b\xcd\xd8\x83\x0d\x96\x7b\xa4\xf8\x38\x02\x1a\x0f\x78\x54\x1d\xd4\xb8\x9a\x98\x23\x98\x3a\xca\xeb\x78\x04\x1f\xf5\x53\xf1\x3a\x06\x0c\x1f\xc5\xe9\x78\x30\x29\x88\xa2\xbe\x89\x2e\x93\xe8\xe2\x73\x9d\x2c\x24\x41\xd6\x44\xd2\x75\xb9\x40\x59\xd5\x20\xd4\x9d\x1c\x37\x2f\x9c\x16\xc7\x09\x41\xa7\x2f\xd0\xdc\xd1\x04\x50\x8e\x6f\x30\xa8\xcd\x6e\x31\x9d\x67\xb0\x6f\x78\x5f\x1b\x97\xa5\xdd\x0e\xa4\x35\x23\x5d\x76\x71\x98\xfb\xd4\xaf\x55\x8c\x14\x77\x61\xda\xfd\x75\xeb\x31\xb5\x2b\xdc\x18\x87\x3c\x73\xdf\x54\x10\x04\x8a\x34\xbc\xe3\x2b\x31\x65\xeb\x48\x6f\x5e\xc9\x2d\x19\x4a\x41\x7e\x87\xe6\x68\x00\xfb\xb4\x79\x4a\x78\xee\xc8\x54\x97\xa1\xf4\xa4\xb8\x9a\xa4\x81\x1d\x92\xaf\x51\xaa\x1e\xb6\xbf\x7c\xaa\x8c\x4d\x28\xb0\x03\x6b\xd3\x44\xba\xa7\xc8\xdc\x23\xac\xda\x88\xbb\x4e\xac\x9f\x38\x7f\xb7\x5b\xbb\xd1\xfd\x74\x0b\xc0\xd3\xe2\xb0\xdf\x2c\x26\xde\x9a\x6f\xa7\x59\xee\xc9\xf6\x4e\xd6\xe6\x1f\xb3\xaa\xf9\xdc\x65\x57\xb9\x41\xfd\xbe\xec\x22\xd0\xe8\x0f\x3a\x1c\x8b\xa7\x2b\x1e\xf1\x5e\x1d\x6d\xbd\x0e\x73\xcf\x63\xf7\x7e\x92\x59\xc5\xb6\x52\x17\x23\xb6\x76\x8c\xd9\xef\x93\x24\x5f\xe0\x23\x0d\x0d\x1c\xe2\xfa\x29\xf7\x8d\x13\xca\x1e\x0e\xdb\x11\xbf\x18\x9b\x4f\x4e\x02\x5b\x1b\x50\xba\x9f\x0c\xc9\x61\x0c\x51\xd4\xdb\x6d\x5b\x03\x5b\x16\x9e\x99\x47\x28\xb5\x27\x26\x8a\x2e\x17\x74\x4f\x61\xab\x54\x8e\x75\xf3\xca\x62\xb5\xd3\x99\xf3\x54\xf2\x72\x4d\xf3\xdd\xc1\x56\x71\x9f\x3e\xad\x4d\x2c\x76\xfb\x5f\x7e\x79\x79\xb9\x23\x23\xed\x1a\x7f\x19\xdd\xb1\xaa\x92\x62\xb1\x22\xa7\xfe\x69\x8e\x18\x3e\xa8\x9b\x9c\x52\xf0\x2b\xf9\xb7\x83\xfb\xed\xbc\x3e\xa7\xff\x5b\x23\x09\xeb\xa4\x00\xe3\x78\xb7\x96\x84\x75\x52\x80\x81\x8d\xc3\x92\xb0\xd3\xf5\x26\x2a\x96\xc3\x3b\xc8\x77\x93\xb6\xe0\x06\xdd\x53\xd6\x96\x24\x64\xc8\x16\x0b\xf5\xe4\x82\xb6\xa7\x06\x09\x82\xda\xf1\x0d\x07\xe1\x6c\x09\x97\x0b\xc2\xdf\x51\xc0\xfa\x84\xab\x75\x81\xfa\x74\xee\xcf\x77\x13\x30\x1f\x8b\x59\x2a\x83\x3d\xe2\x77\x14\xb2\x2e\x20\x4b\xb8\xa5\xca\xe3\x24\x8b\x27\x24\x65\xae\x62\xa4\x95\x35\x2c\x3f\x29\x78\xb6\x70\x77\x77\x58\x36\xc1\x4f\x65\x40\x67\xa5\x97\x23\x5d\xb1\x8a\x89\xb1\x83\x74\x45\x8d\xea\x62\x48\xb3\x15\xe3\x79\x8e\xb9\xcb\xa5\x78\x88\x9e\x39\x1f\xac\x4b\x28\x49\x7c\xf0\xad\x57\xbb\x75\xc9\x3a\x2e\xd8\xd3\x6c\xa8\x24\x38\x05\xe5\xc1\xef\x21\x7b\x00\xe2\x93\x17\x3b\x9c\xc5\xba\x5d\xd2\x07\x64\x76\x25\x8e\x48\xb0\x9d\xc5\xd4\x6e\x0d\x46\x40\xda\x72\x86\xd9\xc0\x3d\x22\xe6\xc5\x0b\xdf\xe8\x48\x56\x2b\x16\xf8\x68\xd2\xf5\x6a\x59\x99\xd5\x4b\x59\x4f\xd8\xcd\x82\xd7\x7e\x08\xed\x13\xe4\x3c\x39\xd7\x2a\x39\x07\xc6\x7f\x6e\x6d\x76\xb7\x95\x3a\xdd\xdd\x3b\x40\x7a\xce\xd9\x5c\x17\xc4\x72\x2c\xad\x01\x52\xb2\x33\x41\xc3\x9f\xf9\x5b\x2a\x37\xf6\x02\x4a\x0d\xf5\x0c\x99\x1c\xf5\x43\x3c\x7f\xe5\x78\x63\x1e\x14\x9b\x35\x7a\x35\x53\x1f\x99\x5c\xf2\x5b\x11\x23\x69\xa1\x3b\xe0\x91\x19\x18\x22\x1c\x42\x99\x01\x0f\x70\xc9\x65\x44\x4d\x02\xf1\xc0\xa5\x71\x4d\x31\xac\xe8\x35\xb3\xe8\x95\xbc\x56\x15\x95\x70\x00\xfe\x62\xa7\xda\x16\x1c\xee\xfb\xe1\x12\x7d\x73\x6e\x78\x27\x25\xe1\xab\x41\x11\x01\xd2\x7d\xc8\x65\x3d\x2c\x19\x4b\x91\xcb\x66\xe9\x8e\x7f\x2d\x73\xfe\xeb\x2f\xbf\xdc\x4a\x30\x5a\x42\xf1\x47\x77\xcd\x3e\xb1\x90\x26\x34\x06\x9e\xff\xf7\x89\xd5\x19\x2d\x28\xc9\x55\x5f\x30\x8f\x2e\xe9\xa2\x9c\xd1\x8b\x60\xac\x10\x67\x65\x19\xee\xed\x88\x0b\x0f\x90\x67\x1a\xfe\x1e\x0c\x24\x08\x7b\x4b\xe7\xfa\x1e\x86\x3f\xaf\x1f\xac\x65\x56\xd3\x99\x81\x6e\x1f\x57\x55\x08\x6e\x59\x56\x73\xed\x0f\xe8\x74\x15\x98\x86\xc1\xb8\xb8\x99\xfd\x6c\x2d\x17\xc3\xbb\xde\x98\x9f\x30\x55\x87\x7e\x15\x1a\x4a\x55\x5d\xb0\xbf\xbd\x7e\x39\x5e\x49\x8d\x97\x40\x74\x6b\x74\x05\x70\x8b\x50\x98\x2d\xe5\x11\xa8\xfd\xf9\x81\xec\xfe\x8d\xd2\x08\x6c\x3d\xc3\xc9\x9e\x59\x6a\x9e\x61\xa1\xbb\xb3\x49\x2b\x5a\xa5\x2b\xaa\x3b\x89\xa9\x2f\x92\xd0\x2f\xaa\xbb\x88\x69\x1c\xf9\xdd\x2f\xaa\xdb\x8a\x29\x42\xdc\xee\x58\xb0\x49\x4c\x01\xa6\x17\x55\x78\x88\x8e\x3a\x10\xb3\xef\x3c\xdd\x8f\x21\xc4\x03\x6a\xf4\xeb\xaf\x0f\x25\xb6\x5f\x7f\xfd\x94\xd4\xe8\xd7\x5f\x3f\x9a\x1a\x85\xff\xfc\xae\x46\x47\xaa\xd1\xaf\xbf\x9e\x1c\x49\x8f\x7e\xfd\xf5\x27\xa2\x47\xbf\xfe\xfa\x51\xf4\x68\x9f\x9c\xfe\xae\x47\x77\xd3\xa3\xdf\x7c\xf3\xcd\x81\xc4\xf6\x9b\x6f\xbe\x79\x42\x7a\xf4\x9b\x6f\xbe\x79\x24\x3d\xfa\x11\xff\xf3\xbb\x1e\x1d\xa7\x47\xad\xd8\x1c\x45\x8d\x5a\xc0\x9f\x84\x1a\xb5\xa2\x7a\x7a\x35\xda\x2f\xa6\xbf\xab\xd1\xc7\x39\xd5\x77\x4f\xf4\xa7\x12\xda\x11\x27\xfa\xdf\x4f\xdf\x07\x3d\x7d\x1f\x48\x50\x3e\x09\xdd\x06\x47\xed\x1d\xe5\xc7\xe5\xda\x1f\x46\x0f\x1d\x24\x57\xa9\x47\x7e\x00\xe2\xd3\xd1\x43\x7b\x1e\x8b\xbb\x47\xe2\x27\xa0\x87\xdc\x91\xf8\xf7\xe3\xeb\x41\x8f\xaf\x07\x12\x94\x4f\x43\x0f\xd9\xa3\xea\x8e\xf2\xf3\xbb\x1e\x3a\xfd\xb1\xb2\x7b\xa4\x7c\x7c\x3d\x04\x76\xba\x6f\x38\xd4\x2f\x48\xf6\x5d\xae\x7f\x3f\x06\xee\x72\x0c\x3c\x90\xc0\x7c\x12\xfa\xc8\xcb\xd2\xf6\x72\x84\xea\x68\xa3\x2c\xfd\x7e\x4e\xeb\xd1\x4b\xa1\x8a\xd3\x78\x49\xa3\xef\x55\x19\x05\x57\xc3\x08\x71\x93\xef\x10\x80\x5c\xd7\x22\xa3\x50\xb8\x53\x3b\xc0\x52\x19\xf2\x47\xf9\xd1\xfa\xe8\x14\x3b\xd7\xa9\x14\xca\x7e\x9c\xc6\x25\xd5\x62\xb0\x63\x6e\x88\x5b\x3d\x01\x83\xc7\xeb\x97\x7d\x76\xa2\x88\xf3\xce\xa9\xb4\x6f\xa4\x61\x57\x37\x60\x2a\xc7\xf1\x55\x00\xfb\xb9\xe6\x55\x25\x6a\xbf\x44\x42\x56\x31\x71\x7a\xc2\x4a\xc5\x6a\xde\xdb\x64\xbc\x2b\x1e\x0f\x04\xae\xb5\xf5\xd8\xc9\x67\xbc\xd1\x02\x20\x59\xbd\x9b\xcb\x50\x7b\x77\x21\x4a\xd6\x68\x4a\x4f\xf0\xe9\xc2\x51\xe1\xed\x51\x05\x20\xbe\xba\x8c\xfb\x28\xfe\x93\x10\xb0\x8c\xfc\xca\xf5\x89\xd7\xae\x55\x90\x0b\x5d\xd5\x51\x1a\x75\x4f\x9c\xcd\x34\x74\x34\x78\xf3\x96\x5a\x57\x3c\x70\x09\xbc\xb3\xb8\xd2\x20\x9d\x88\x98\x2f\x7a\x0a\xb9\x22\xa9\x02\x47\x3e\x10\xa9\x46\x73\xe6\x46\x64\xb5\x30\xae\x79\x54\x0f\x93\x5c\xfd\xf1\xbd\x19\xe5\xea\x98\x6f\xe8\xee\x81\xf8\x44\x59\x1d\x6d\xb4\x3a\x95\x5d\x21\x7c\x28\xee\x12\x81\x01\x48\x14\x36\xa7\x0d\xaf\xb1\x25\xfa\xda\xb9\xae\x71\xfa\x1e\x94\x11\xd7\xb5\xfa\x17\x56\x13\xe8\x14\xa0\xa8\xf0\xd1\xa6\xe8\xdc\x00\x21\x53\xcb\x99\x2c\x45\x1e\xa5\x8d\xd8\x27\x50\x67\x21\x53\xcb\x4a\x95\x60\x86\x60\xa5\x12\x7e\x87\x74\x69\x2a\x0c\xf2\xf2\x83\x41\xa4\xe5\x2f\xd7\xfe\xef\x5f\x77\x8f\xa2\x4c\x1b\x5d\x55\x1e\x51\x17\xc7\x49\x4d\x75\xa1\x15\x85\x65\x85\x9e\xd0\xc2\x74\xdd\x74\xa1\x58\x6c\x14\x3d\x0a\x90\x42\x63\xb5\xac\x6a\x06\x1a\x45\xb6\x9e\xf8\x2e\x9c\x3e\xc5\xa4\x1d\xbf\x0b\x95\x15\x0c\xf6\xac\x6e\x61\xe2\x7a\xfa\x7a\x7b\x2e\x81\x1d\xd2\x87\xa1\xc0\xcc\x83\x28\x0a\xfb\xbf\x03\x08\x74\x03\x22\xfb\xc3\x47\xc7\x2b\x5f\x4f\xd5\x0f\x8e\xfd\x9b\x45\xac\x53\xc3\x66\xcb\xea\xbc\xb1\xc8\x6d\x53\xa7\x17\x77\xb2\xe1\xaa\x19\x5b\x37\x34\x31\x8b\x5a\x24\x61\x8d\xf0\x6b\xa4\xa0\x2d\xfa\xc5\x0a\xca\x73\xc3\x3c\x49\xe4\x5b\x73\x8d\xb3\xd4\xae\x7c\xc3\xe3\x70\xc5\x53\xa2\xd6\x70\x65\x39\xac\xfa\x82\x6d\xdd\xcf\x7e\x23\xdc\x60\xfc\xb7\x16\xc5\x55\xab\x3f\xb7\xb5\x27\xe0\x5f\xe7\xcf\xce\x50\x5a\xfd\xac\x03\xad\x5d\x2b\x16\x7c\xe2\x07\x99\xf8\x68\xe2\x41\xe9\x4e\x97\x97\x17\xc6\x36\xa4\x24\x0a\xbd\x33\x2e\xcd\x33\x1a\xd7\x8d\xd9\x8e\x51\xf6\xe3\xba\xca\x21\xad\x45\x95\x74\x8b\xef\x8c\xe3\x05\x31\x49\x23\xf4\xf3\x73\x2d\xaa\xbb\x93\x0b\x13\xeb\xf0\x77\xa7\x75\x35\xd0\x76\x78\xed\xc2\xda\xd2\xf4\xed\x5b\x52\x63\x4b\x5d\xed\x19\xeb\x1e\x0b\xe4\x90\x8e\x3e\x0b\x55\xc9\x71\x13\x55\xd4\xdf\x31\x16\xcb\xb8\x71\x5b\x64\x67\x02\x0d\xa6\x1b\xe5\xd2\x9e\x91\xd1\x20\x9d\xb7\x2a\xcf\xe8\x06\x42\xdd\xe7\x4d\x61\x97\x32\x69\x61\x97\xda\xd4\x3e\x6d\xcd\xe2\x3b\x8c\xd3\xb1\x7b\xf4\x7d\xf9\xde\x8c\xde\xa7\x8a\xd9\x11\x98\x1e\xa3\x93\xd4\x19\x63\x58\x67\xec\xb7\xcd\xf6\x6d\xf2\x42\xf7\xe6\x7c\xbc\xbe\x0e\x52\xa2\xf7\x58\x3a\xa0\xb5\xf6\xbd\x8f\xed\xcb\x53\x0b\x44\x9c\x20\x48\x6d\x36\x0e\x95\xb7\x07\x02\x85\xb9\xa8\xbb\xf8\x52\xf6\x15\x3c\xdf\x4b\xe2\xc8\xe2\xb6\x73\x25\xdc\x93\xef\x2f\xef\xdb\xd5\xca\x78\xa1\x55\x52\x37\x31\xaa\x00\x5d\x71\xb3\x18\x27\x8a\x5d\x31\x0c\x56\x13\x16\x50\x83\x2a\x02\xce\xcd\xf0\x29\x28\x2d\xa4\xc9\x63\x28\xaf\x23\x95\xb5\x7d\x14\x3d\xb6\x41\xde\x1c\xc4\x50\x64\x6f\x5f\x79\x43\x43\x38\x95\xb9\x9d\x74\x22\xc9\xdb\x6f\x54\x27\x9e\xd2\x16\x6b\x09\xf5\xa7\x65\x99\x6d\x54\x98\xb1\xc0\x1d\x50\x61\xa2\xc7\xe4\x00\x02\x7c\x3a\xc1\x6a\xd5\x84\x85\x92\xa7\x07\x11\xac\x9e\xf2\xb0\xce\x49\x62\x5c\xc7\xc5\x5d\xca\xc3\x6e\xeb\x83\x1b\x23\x50\x3e\x39\x39\x48\x4c\x10\x16\xf3\xa0\xa2\xf6\x83\x7e\x67\x81\x52\xae\x9b\xdd\x03\x2d\xd1\xc9\xfa\x4d\x3e\x2f\x47\x76\xb0\x68\x15\x6e\x5b\x31\x76\x5f\x71\xd8\x5c\x3f\xb6\x8f\xff\xc7\xeb\x5f\x75\x0c\xdd\x51\xe6\x56\x87\xdb\x31\xb5\xf7\x9e\x45\x0d\xe7\xed\x97\xa5\x78\x70\x5e\x9c\x1e\xbd\x80\xca\x03\xbf\x4b\x79\x0a\xd8\x91\x8f\xab\x5f\xa5\x34\xc1\xf9\x84\x5e\xb1\xa8\x62\xb2\x85\x73\x2b\xa1\x64\xae\x22\x28\xcf\x8f\xcc\xfa\xc8\x45\x3b\xb6\x68\x6c\x00\x12\xbb\xaf\x4f\x51\x36\x76\xbc\xcf\xbd\xed\x58\xc7\x8d\x7b\x0f\xe7\x7a\x87\x97\x2e\x4e\x2b\xac\x73\x37\xc9\xa3\x3a\xc2\xa3\x9a\x01\x3b\x30\x77\x44\x29\xca\xdd\xb8\x7b\x98\x12\xb2\x4f\x9e\xbf\x9d\x22\x94\x4f\x89\xc1\xa3\x6b\xc9\x6e\xcf\xe2\x03\x56\x93\x7d\xd2\x3c\x1e\x28\x26\xfb\x04\xb9\x7c\x94\x95\x7c\xd0\xb2\xb2\x9f\x02\xa3\x9f\xf4\x7a\x8e\x8a\xcb\x6e\x53\xd8\x73\x14\xdb\x1f\xbf\xac\xec\x63\x8a\x07\x1e\x0f\xaf\x7f\x6a\x5f\x75\x87\xbe\xc5\x73\x68\xe1\x49\xf7\xda\xf6\x2d\x07\xb6\x16\x10\xc8\xb2\xae\x30\xed\xe6\x23\x41\x87\xbe\x4f\x5b\xd7\x9c\x4e\x08\x1f\xa7\xbe\xec\xef\xa2\x68\x3e\x85\x9d\x6f\x4c\xa1\xd9\x51\x72\x77\xc0\x52\xb3\x4f\x7a\x93\xab\x3a\x75\x20\x9f\x12\x3b\x77\xf3\xd0\xf7\xb0\xf5\x04\x85\x67\x1f\x93\xcd\xef\xe3\x55\xea\x22\xad\xdd\x52\x8f\x9d\x51\x16\xd3\xf1\xb7\x91\x89\x70\xa0\xe8\x6c\x14\x90\x50\x79\x3a\xe2\xdd\xb2\xd1\xe6\xd3\xb9\x91\x7c\x22\xf2\x7a\xcc\xe2\xb5\xbf\x0b\xeb\xef\xc2\xda\xa9\x5d\xbb\xb3\xb4\x1e\xbd\x0a\xee\xe3\x89\x2b\xfc\x16\x15\x90\x85\x0a\xa6\x23\xc2\x68\x7b\x8b\xe0\x6e\xde\x5a\x19\x7b\x11\x7d\x48\xc5\x29\x4b\x17\x3e\xb8\x61\x05\xb8\x20\x43\x8a\xd7\x9d\xab\xda\x2f\x83\x08\xea\xa3\x08\x19\x16\x57\xdd\x57\xc0\x8e\x52\xea\xf6\x91\x65\x0b\xab\xc7\xa2\x58\xf9\x8a\xf1\x83\x2c\x6e\x57\xba\xdd\x20\x51\xec\x07\x47\x77\xb6\xbf\x30\xc1\xcf\x08\xf0\xe8\x32\x74\xe3\xa3\xd0\xd3\xf8\xec\x6d\x62\xb3\x31\x92\x7d\x54\x60\x36\x93\x65\x9c\xb8\x74\xac\xc0\x6c\x8a\xad\xef\x44\x65\x87\x1b\x35\xb6\x4f\x54\x36\x06\x65\x73\x1a\x66\x23\xd4\xc1\x98\x6c\x22\x1c\xdd\x6d\xf9\xc9\xd1\xcf\x32\xaa\xbe\xbb\x7d\x00\x36\x01\x69\x45\x5e\xb7\x63\x9c\xa3\xe8\x6b\x3f\xea\x86\xd0\xeb\xf6\x68\x1e\x49\x27\xc8\xe9\xac\xa2\xb8\xeb\x74\x84\x2e\xed\x93\xf3\x71\x27\xe8\xba\x3d\xa1\x43\x44\x5c\x23\xcc\x2d\x56\xc9\xce\xc1\xd6\x84\xfd\x23\x44\x5a\xaf\xb9\x8b\x47\xa4\xc2\xed\x2c\x45\x62\x10\xae\x4e\x48\xbd\x4b\xe3\x4e\xac\xb6\x0f\xbd\x26\x07\x4a\xff\xfd\xbb\x85\x38\x1c\x97\xd1\x0d\x5d\x63\xb3\x95\x1b\xfc\xe0\xec\xee\x32\xdb\x17\x14\x73\xb1\x29\x73\xfd\xb7\x5a\x35\xd5\xf1\x38\x1e\x47\xd2\x74\x82\x70\xa1\x9b\x37\x62\x70\xa4\x40\xb6\x83\x8a\x4a\x52\x74\x63\xc1\xf5\x70\x90\xdb\x97\x97\x13\x36\xd7\xb7\x44\x5a\x5f\x84\xec\xd9\xe5\xe5\x33\x8c\x04\xd0\xa2\x76\x3f\x86\x40\x23\x99\x5b\x29\xda\x1c\xfb\xed\x55\xde\x0e\x72\x77\x4e\x47\x93\x34\x3d\x1a\x63\x41\x8e\x96\x24\xbb\x5f\x31\x86\x03\x29\xb7\xf1\x87\xea\x5d\xe4\xfc\x44\x01\xe6\x47\x50\x7d\x43\x42\xfc\xf1\xcb\xcb\x4b\x17\x48\x06\x4d\x0b\x36\x5a\x98\xbb\x88\x24\x40\x6c\x1f\x97\xf7\x3d\x2a\xe3\xc4\xf7\xcf\xda\xdf\x43\xf2\xb6\x09\x32\xdf\x59\xde\x0e\x1c\x61\x7e\xca\x7d\xf5\x7d\x64\x3d\x25\xe1\x93\xce\xcd\xbc\x47\xfc\x6f\x5b\xf0\xbc\x19\xdb\xab\x0f\xf1\xff\x5c\xa3\x8f\xb8\x9f\xfa\x09\x05\xe5\xe4\xaa\xaa\x1b\x4e\xfe\xdb\xd0\x5a\x3e\xbe\x3c\x15\x2e\xda\xe0\x42\x42\x83\xd7\x0e\xd8\x61\xed\xd8\xe2\xc5\x7a\xe5\xeb\x04\x45\x6c\x4e\x2a\xc3\x21\xff\x7e\x7c\x94\xef\x3a\x09\x5e\x13\xe2\xcb\x4f\x13\xdb\xbb\xab\x91\x18\xa4\x6f\x5c\x9c\xef\x66\xaf\xe0\xa6\xcd\x75\x7d\x84\xef\x4e\xf2\x79\x40\xe1\x21\x51\xf1\xa2\xb3\x53\xee\xbc\x03\x32\xd2\x2d\xb3\xcf\xc1\x73\x5b\xb7\x4c\x22\x36\xce\x4b\xe3\x42\x83\x87\xe6\xba\x7d\xee\x3c\x40\x04\x57\x4d\xea\xa8\xd9\xc3\x49\x93\x26\xca\xa7\x0e\x8d\x9d\x9d\x34\x5b\xa4\xc8\x8f\x75\xd2\x6c\xcc\x8f\xdf\xd5\x49\x93\x2e\xbd\x23\x3a\x69\x48\x56\x06\x7a\x71\xb5\x57\x48\x8f\x5f\x66\x92\xe8\x1d\x48\x70\x80\x5b\x2b\x59\x06\xbd\x02\xb3\xb1\xbf\xea\x6a\x43\x49\x20\x37\x60\x58\x3c\x8e\xb4\x74\x83\x66\x95\x2c\x61\x51\x8b\x5b\x5e\xe7\x85\x6b\x34\xab\xe6\x8c\x47\xaa\x8c\xb0\x12\x1f\xa5\x86\xcd\x68\x0d\x7a\x01\xb5\x9d\x22\x23\xda\x72\xda\x1d\xc9\x6a\x3f\x3f\x86\x9e\x76\x17\x72\xac\xbf\x53\x65\x1f\x75\xae\xeb\xa9\x5c\xb3\xf9\x44\xee\x74\xc1\x40\xe3\xb6\x68\x3d\x74\x9a\xd4\xd9\xe5\x0b\xe1\x22\x0e\xc6\xc3\x42\x66\x0b\xef\x7b\xe7\x5a\xab\x4c\x86\x25\x1c\x88\x88\x45\xd4\xab\x64\x53\xc3\x1d\x28\xf4\xfc\xa4\x1d\x23\x5a\x99\x5b\xb9\xa1\x9e\x3d\x3f\x90\x44\x8f\xf0\x2e\x76\x65\x72\xbd\x3d\x7b\x08\x21\xea\x91\x91\x4d\xf2\x41\x46\xc8\x76\x32\xd2\xd1\x24\xa9\x78\xb4\x54\x66\xaf\x88\x98\x61\xbe\xf6\xf0\x14\x35\xe6\x0e\xee\xc5\xdd\x15\x95\xf3\x7c\xa1\x4b\x2f\xb8\xbb\x28\x71\xee\xa0\xac\x8f\x3c\x8b\xfd\x1e\x98\x43\x7a\x17\x8f\x26\x33\xf8\x6d\xa7\x41\xef\xe5\xc7\x2f\xbf\xbc\xec\xe9\x83\x90\x26\x22\xfa\x93\x87\x9b\x26\xfe\x3e\x90\x1a\x74\x72\x41\x74\xbe\xc6\x19\x5a\x42\x4e\x0e\x4f\xe0\xe2\x39\x40\x09\xd8\x7d\x16\xc1\x81\x25\xbd\x2d\xd9\xde\xa5\xfc\x89\x49\xf4\xc6\x38\x9c\x3e\xe3\x71\xbb\x4d\x74\x8d\x60\xb6\x76\x3e\x7f\xf2\x89\x34\xe4\xd6\x92\x89\xd6\xd6\x71\xce\xe3\xdb\x09\x20\xf9\x73\x0e\x2f\x77\xce\x51\xb4\xdf\x31\xea\x38\x42\xb6\x8d\x8f\x30\x52\x7a\x9d\x08\xaf\xb6\x6c\x85\x03\x7d\x02\xff\xa0\x66\xd5\x81\x19\x7f\x0a\x15\x94\x88\xc2\x61\xfd\x86\xa7\x14\x14\xdc\x31\x37\xeb\x27\x9c\xe6\x76\x9b\xe7\x26\x19\x02\x98\x6b\xe4\x68\xb0\xd8\xc4\x53\xf1\x12\xee\x24\x9c\xdb\x57\x01\x58\x2b\xa0\x3d\x6e\x41\xef\x12\x3c\x96\x9a\xb2\xe7\xca\x3e\x09\xd4\x23\x44\x50\x96\x5d\xf7\x5f\x24\x14\x3d\xb1\xf6\x9d\x48\x94\xb6\xd4\xcd\x14\xd6\xc7\x6d\x89\x9f\x4e\xdd\x80\xbd\x32\x78\x30\x66\x9f\xdd\x34\xb3\x6b\x6e\x16\xdf\xb2\x77\x82\x43\xdb\x73\xe7\xa3\x04\x24\x78\xa8\x14\xec\xfc\xdd\x67\x6b\x59\xde\xcc\x60\x75\xbe\x30\x6a\x29\x33\xf6\x50\x4b\xd3\x2d\x7f\xeb\x25\x1a\x5f\xd6\xe1\x48\x1f\x06\x03\xc7\x70\xac\x8b\xd6\xf3\x3e\xb8\xcb\xbc\x5b\x39\xe3\x25\x2e\xf8\xc1\x09\xf5\x98\xcc\x70\x64\x67\x0f\xbc\xdb\x02\x9f\x3b\x74\xb7\x32\x30\x70\x56\x10\x0c\xea\x3d\x32\xb9\xbc\x97\x79\xc3\x0b\xca\x40\x90\x65\x84\xfe\x98\x73\xbb\xab\xad\xeb\xf0\xf9\x84\x38\x8a\x3b\x90\xa5\xc3\x35\x34\xe6\x9f\x07\x7f\x53\x3b\xc0\xfd\x09\x71\x1c\x63\x80\x0b\xad\x58\xa3\xe1\x2c\x82\x70\xe0\x11\x14\x13\x96\x3a\xba\x8c\x42\xcb\x57\x6e\xdb\x26\x63\xad\x90\xb8\x0b\x93\xd3\x0a\x4a\x1c\xef\x7a\x02\x51\x71\xc3\x1d\x71\xed\xc7\x33\xfa\x0f\x5d\xfd\xed\x5b\xb2\xa3\xb2\x34\x0c\x76\x3c\x9e\x86\x31\xfe\x43\x39\x9a\x58\x34\x47\x65\x27\x8d\x74\x3c\x5e\xd2\x00\x2d\x73\x3c\xf8\xd1\x0f\xc7\x48\x62\x62\xb8\x5d\x3d\x0e\x23\xff\xf0\xff\x05\x00\x00\xff\xff\x31\x1c\xfc\xfb\x13\x9a\x02\x00") +var _testConformanceTestdataConformanceYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x5b\x73\x1c\x37\x92\x30\x0c\xdf\xcf\xaf\x40\xf8\x86\xe3\x27\x9a\x2d\x4a\x3e\xcd\x78\x3e\x7f\x11\x32\x25\xdb\xda\xb5\x25\x8e\x28\xdb\x17\x5e\x87\x1e\x74\x15\x9a\x8d\x61\x75\xa1\xa6\x80\x22\xd5\xfb\xc6\xfb\xdf\xdf\x40\x66\xe2\x54\x87\xee\xea\x23\x29\x8f\x77\x27\x66\xc4\xae\xaa\x44\x22\x33\x91\x48\x24\xf2\x70\xce\x8c\xd0\xa6\xe4\x4b\xf1\x35\xbb\x52\x39\xfb\x51\xce\x45\xb6\xca\x0a\x31\x61\x95\xd2\x86\x69\xc3\x6b\xc3\xc4\x07\x91\xb1\x85\x52\xb7\x7f\x61\x2c\x53\xb9\xc0\xf7\xcf\x7e\xbb\xfd\x9b\x9e\x4a\xf5\x3b\xbb\x54\xa5\xe1\xb2\x14\x75\xf8\x9e\xfd\xa0\xd4\x2d\xbb\x5f\x88\x92\x65\xb5\xe0\x46\x30\xce\x2a\x95\xb3\x7b\x69\x16\xac\xf0\x6f\x11\x50\xc6\xf4\x42\x35\x45\x0e\x23\x35\x46\xc0\xe0\xad\xb1\x59\x55\xab\x4a\xd4\xc5\x8a\xfd\xf6\x5a\xe5\xe2\x52\x95\x73\x55\x2f\x79\x99\x89\xdf\xd9\x6f\xf1\x5f\x67\x7f\x61\x2c\x17\x3a\xab\x65\x65\xa4\x2a\xbf\x66\xbf\x5a\x2c\x78\x3c\xa1\x05\x2f\xf3\x42\xd4\x4c\x6a\xa6\x2b\x91\xc9\xb9\x14\x39\x93\x25\x33\x0b\xc1\x32\x3f\x99\x80\x66\xa3\x65\x79\x03\x78\x72\x76\xf6\xf2\x83\xc8\xce\x18\xcf\x2c\xf0\x89\xfd\x04\xbf\x73\x30\x7f\xfa\xf9\xfa\x1d\x9b\x09\x26\xcb\x3b\x75\x2b\x72\xc6\xe7\x46\xd4\xf0\x06\x8e\xad\xe6\xe9\x30\x53\x80\xfb\x9c\x69\x51\xdf\x89\x1a\x88\x24\x35\x11\x2d\x67\x66\xc1\x0d\xbb\x97\x45\x81\xcf\xd9\xc2\x98\x8a\xd5\xe2\xdf\x8d\xd0\x46\x4f\x02\x6d\xb5\xc8\x54\x99\x7b\x12\x13\xae\x7d\x73\xc1\x09\xaf\x64\x79\x93\xd2\x04\x46\x42\xa4\x35\xa2\x1b\x10\x0a\xf3\xb7\x93\x7f\x0e\x53\x67\x46\xb1\x3b\x5e\xc8\xdc\x22\x00\x1f\xdb\x8f\x22\x80\x52\x3b\x76\xe6\x76\x8e\xb5\x28\x04\xd7\xe2\x6b\x76\xf7\x74\xfa\xf7\xbf\x30\x36\x97\x85\xf8\x1a\xc4\xef\x89\x78\x26\x9e\x64\x6a\xb9\x54\xe5\x13\x8f\xe7\x7b\xcb\xf3\xe9\x8d\xfa\xcb\x38\x11\x05\xba\x3c\x90\x88\xfa\xb1\x1f\x8b\x88\xfe\x60\x4c\xf5\xbd\x30\xff\x59\x32\x1a\x89\x23\x40\x7e\x20\x91\xac\x85\x36\xaa\x7a\x08\x95\xd9\x1e\x79\x7f\x69\xac\xc5\x39\x80\x3c\xa5\xba\x9c\x89\xb9\xaa\x45\x0b\xb4\xd4\xcc\x88\x7a\x29\x4b\x4e\x9c\x7b\x38\x61\x74\x34\x39\x90\xba\x74\xe0\x4e\x27\x99\x0f\xa0\x29\xdb\x23\x3f\x12\xc9\x24\x35\xf9\x1f\x26\x9c\xc3\x7a\xf2\x88\xb2\x18\x84\xea\x6d\x53\x1a\xb9\x14\x13\xf6\x8e\x68\x26\x55\xf9\x93\xd0\x9a\xdf\x88\x09\x9b\xd7\x6a\xc9\x0a\x75\xc3\x54\x63\xaa\x06\xf6\x21\xdd\x64\x99\x10\xb9\x9d\xa0\x9f\xff\x46\xc9\xa5\x41\xd8\xac\xe0\xd9\xed\x4c\x7d\x00\x4c\x98\x5d\x84\x9e\x51\x11\x35\x51\x5c\x81\x18\xb5\xa8\x94\xdd\x67\x02\x6e\x6c\x89\xc8\xb1\xdf\x7e\x94\x65\xf3\xe1\x4d\x59\xac\x7e\x67\x5c\x33\xb1\xac\xcc\x0a\xd7\x84\xa5\x2a\xa1\xa9\x19\x2f\xf3\x9e\xa9\x5d\xa9\x42\x66\x2b\x18\xe2\x3b\x5e\x14\x33\x9e\xdd\xbe\x53\x3f\xaa\x1b\xfd\xa6\x7c\x59\xd7\x0a\x05\x58\x98\xad\xd7\xc3\xd9\x65\x67\x3d\xf2\x32\xda\xb7\x03\x4d\xce\xce\xb4\xa3\xaa\xd4\xac\x16\x99\xaa\x73\x58\x2b\x80\x94\xa5\xb9\xc5\x3c\x10\x45\x7c\x90\x46\xe3\xb4\xb4\x9e\x37\x45\xb1\x02\xf0\xaa\x31\x76\x04\x61\x91\x9e\xe2\x72\x1c\x58\x09\x13\x94\xae\x0e\x29\x70\x51\x2d\xf8\x9d\x60\xa5\x82\x8f\x45\x69\x2c\x45\x23\x86\x20\x31\xa7\x31\xcd\xbf\x66\x97\xbc\x2c\x95\x01\xa8\x4b\xd5\x94\x06\x04\x51\xdb\xd5\xfe\xab\x2c\x73\x75\xaf\xc3\x64\xf5\xf4\xac\x25\xb8\x4f\xbf\x18\x94\xdc\x1a\x85\x65\x1f\x91\xb5\x80\x1f\xad\xb0\x06\x0c\xff\x28\xd2\xca\x71\x3a\x16\xf9\x54\x15\xef\x26\xb4\x89\xa0\x8a\x7c\x32\x28\xb4\x4b\x6e\xb2\x05\xe2\xed\xc6\xb5\xb2\xeb\x09\x9c\x0a\x2c\x80\x45\xa1\x7d\x74\x02\xeb\xa7\x7f\xa6\x53\x7d\x0b\x48\xcf\xb9\x2c\x1e\xa1\x0c\x47\x88\xca\xf9\x47\x28\xb6\x43\x4a\xd6\x41\x1c\xa3\x54\x63\x4a\xa1\x2a\xec\x0a\xa8\x95\x4d\xf1\xa1\x12\x99\xa5\x3a\xa1\xe3\x71\x69\xb1\x1f\xf9\xff\x11\x08\xee\x15\x37\x8b\x09\x2b\x55\x79\x5e\x2b\x65\x58\xa3\x45\x0d\xc4\xb4\xbf\xe4\x62\xce\x9b\x02\xb7\x86\x8a\x83\xbd\xf4\xb0\xe2\xda\x2f\x9e\xdc\x2c\x9c\x08\x72\xed\xa7\x02\x70\xfd\x74\xb8\x61\x3c\x9e\x13\xcc\xe7\x20\x12\x1b\x4d\xc8\x28\x56\x37\x25\x93\x80\x07\x6f\x11\x15\xdf\x06\xac\xb2\x46\x1b\xb5\x1c\x9a\x8a\x16\x66\x0a\x87\x8c\x5a\xe4\xb2\x16\x99\x41\x53\x93\x04\xce\x28\x32\x2a\xd5\x9d\xb4\x72\x47\x7c\x61\x89\x76\x26\x61\x5f\x63\x4f\x83\x51\xde\x4b\xef\x20\xf0\x64\xc6\x76\x85\xbe\x50\x37\x37\xe1\x3c\xe0\x51\xa1\x69\x59\x8c\x5a\x26\xc6\x3b\x0e\x1f\xf8\x9f\x00\x72\xde\x08\x3b\x9b\x46\xc3\x16\x7f\x76\xd6\xc8\xfc\xec\x0c\x98\xd5\x94\x7c\x56\xc0\xc3\x07\x5a\x26\x6f\x05\xfa\x35\x50\xf3\x4d\x80\x1b\x57\x0b\xae\x85\xde\x71\x09\x80\x85\x00\x30\xf1\x44\x11\xc9\xcc\x82\xa3\xa8\xd2\x1e\x8b\x47\x3c\x2b\x46\x7e\x3f\xf4\xe4\xd7\x86\x9b\x46\x6f\x2d\xb5\xaf\xd0\xeb\x54\xd3\xa4\x2a\x98\x94\x5b\x31\x46\xb1\xb3\xe7\xc5\x3d\x5f\xe9\x33\x9c\xa7\x3b\x9b\xd1\xeb\x22\x07\xe4\x3b\x7b\xf9\xab\x79\x0f\xc0\xb3\x37\xe5\x77\x5c\x16\x4d\x2d\x5a\xc0\x1c\x28\x55\x16\x2b\xbb\x8a\xa5\xe9\xda\x07\x38\x61\xbb\x68\xfe\x57\xd4\x0a\xe8\x01\xb4\x9e\x0e\x4f\xe0\xec\xb5\xb8\x13\x75\x34\x16\x80\x2c\xed\x8f\xc9\x14\xa6\xec\x79\x51\x58\x18\xda\x1e\x32\x6b\x21\x90\x2b\x99\xe5\x28\xe2\x78\x27\x6a\x39\x5f\x25\xc3\x64\x56\xf6\x10\x49\x9e\x59\x2d\x2f\xcb\x9b\x62\xd5\x3e\xb9\x3d\xfd\x6c\x5b\x79\x7b\xa1\xb2\x5b\x51\x07\x11\xd0\x13\xd2\x0d\xf5\x4d\xb3\x14\x38\x64\x9f\x8c\xd1\x77\x41\xf6\x9d\xb0\xcc\x04\x73\xeb\x45\xdd\x89\xba\x96\x39\x1e\xa5\xe5\x92\xdf\x08\xbb\x13\xc5\x7a\xdc\x8f\xc2\xfe\x9a\x13\x22\xcb\xfc\xd3\xad\x65\xea\x05\xa9\x51\x3b\x55\xd0\xaf\x65\xce\x70\x0f\xb4\x23\x13\x64\x40\x80\x89\xd2\xd4\xab\x4a\xc9\xd2\x78\x71\x68\xb4\x40\xbd\x0f\xeb\xc2\x32\x2f\x57\xc2\xaa\x6e\xe3\x0e\xde\x2d\xdd\xe5\x86\x99\x35\x78\xa6\x0e\xb3\x80\x31\x2d\x04\xfb\x21\xc0\x84\x41\x3c\x21\x70\xe5\x39\x1f\xc6\xf8\x73\x37\x4e\xe1\x7d\xe0\xd2\x58\x36\x12\xaa\x47\x65\xa2\x23\x87\x63\x61\x20\xf1\xfe\x9c\x1c\xc7\xc4\xd7\x6f\x3c\x23\x83\x7e\x70\x6c\xb0\xa4\xd6\xfd\x1c\x9c\x32\x76\x19\x0f\xe4\x3e\x69\x71\xcd\x2c\x44\x32\x51\xda\x6a\x00\x97\xd3\xf1\x10\x2d\x87\x93\x2c\xcb\xde\x11\x0f\xb2\x2a\x5b\x4b\x65\x13\x67\x01\x9b\x36\x77\xc7\x70\x36\x1d\x2c\xe2\x33\x2e\x06\x36\xb4\x66\xbb\x9c\x1f\x40\xff\xb4\x32\x60\xcf\xb6\x07\x11\x83\x46\x47\x6c\x77\x3c\xd7\x76\x13\xcc\xba\x04\xd2\x8c\xd7\x60\x3b\x94\xb7\x0f\xc6\xfc\x0e\xe3\xc7\xe9\xe6\xc3\x71\x44\x96\xd2\x9c\xfb\xc7\xe7\xb0\x1b\xeb\x73\x5e\x55\xe7\xb4\x35\x73\xb0\x57\xce\x2b\x35\xa4\x65\x5f\x95\xd2\x04\x93\xac\x4b\x48\x62\x0d\x7a\x72\x61\xbc\x88\xff\x40\x04\x55\x32\xee\xcc\x40\x34\x8f\xc0\xe4\x5f\xcf\x81\x97\xa5\x6e\x6a\xba\x85\xe0\x45\x91\xa2\x81\xac\x75\x86\x10\x30\xa7\x28\xa2\x61\xad\x7c\xe3\x8c\x58\xfa\x96\x61\x96\xaa\xf6\x18\xd5\xb2\xe6\xb5\x91\x45\x61\x4d\xc5\xd2\x1a\x95\x78\x0e\x0f\x36\xb9\x3d\x0c\x58\xc3\x7a\x26\x9c\x6b\x3e\xb5\xe8\x80\xb5\x0b\xae\xdb\x66\x15\xd7\xe9\xbc\x3b\x06\xcf\xb3\x41\xce\x5a\x42\x06\xbe\x6e\xcd\x56\xb0\xdb\x4e\xc6\x55\x30\x1d\x4f\xc9\x54\xfb\xe6\x9d\x2a\x9a\xd2\xf0\x5a\x16\xab\x8e\xe5\x0b\x06\x2f\x99\xf8\x17\x13\xef\x85\xd3\x2b\x6d\xc4\xd2\xf2\xd6\x2e\xc1\x1b\x65\x79\x6d\x54\xcc\x50\xc6\xcb\x15\x5d\x2d\x6b\x11\x0f\x3e\x8e\xcd\x40\x88\x63\x71\x79\xce\x65\xa1\xe1\xfa\xe3\x18\xac\x06\xa5\x84\x24\xa8\xaa\x36\xb3\xc1\xc6\xe0\xb2\xa0\xcb\xea\x1c\xce\x1d\xa9\x50\xe0\xf3\xbd\xa5\x22\x1e\xdb\x31\x2a\x59\x6a\xc9\x1a\x4e\xe6\xe6\xfd\x82\xda\xda\x09\x8e\x9d\xf9\xe3\xe4\xda\xa1\xf4\xee\x5a\xb6\x8d\xe1\xd2\x6e\x1a\x79\x33\x9b\xba\xcb\xdb\x0e\x4d\x67\x95\x75\xfc\x11\x39\x9b\xab\x9a\xcd\xc5\x3d\x53\x59\xd6\xd4\xb5\x28\x33\x81\xd7\x00\x55\x2f\x27\x51\x42\x8f\xa5\x6a\xff\xbb\x99\x89\x42\x98\x09\x5b\x28\x6d\x9e\x17\x72\x8d\xe7\x82\x5e\xa5\x73\x52\xb6\x10\x79\x53\xa0\x8f\x62\xd6\xe8\xd5\x4c\x7d\x80\xa9\x82\x82\x8a\x80\xc5\xbe\xbb\xfb\x5a\x1a\xb4\x24\xc0\x36\x54\xec\x89\x30\xd9\x13\xfb\xb2\x4e\x9c\x77\xdb\xda\x33\xde\xd7\xd6\x8b\x00\xe8\xda\x88\x9f\x89\xdd\x6e\x4d\x6e\x70\x55\x01\x82\x11\x3e\x84\x25\xf8\xd7\xd0\x45\xab\xa3\x7b\x33\xf0\x7a\xd9\xc9\xbb\xc9\xa8\x79\x74\xfd\x9d\xd2\x92\x39\x4f\x5c\xb8\x52\xed\x1b\xc7\x92\xb7\x2e\x85\x11\x1a\x7d\x59\x68\x3c\x47\x6f\xc2\x8d\x8b\x2c\x49\xa3\x4b\xa3\x13\x4b\x74\xa1\xee\xed\x3a\x9f\xe0\xc7\x16\x35\x59\xe6\xf2\x4e\xe6\x0d\x2f\x9c\x5b\x8c\x04\xb9\xa9\x2a\x45\x3e\x16\xe7\x27\x43\x87\x73\xb0\xb3\xd8\x77\xaa\x66\x66\x01\x2e\x74\xae\xf1\x66\x1e\xbc\x82\x1a\xfc\xea\x4b\x5e\xdf\xc6\x5e\xba\x2d\x5c\x1d\xb7\x28\x45\x83\x72\x18\xae\x18\x26\xd1\xb1\x67\x37\x79\x8c\xce\x84\xe8\x87\x25\xad\x52\xd5\xb2\x34\xde\x67\x19\xdc\xa5\xc0\xe4\x6d\x85\xef\xdb\x95\xc3\x93\xc2\xb7\x72\xbc\xec\xca\xed\x3f\x45\x5d\x07\x7b\xda\x99\x5a\x60\x67\xf9\x0b\xfe\x70\xa5\x56\xc5\x6e\x30\x51\x06\x0f\xae\x97\xc0\x03\xd2\x19\xd5\x95\x85\x6d\xe9\x5c\x08\x88\x45\xd8\x8f\xcc\x64\xf8\x80\xc2\x85\x7d\x01\x05\xb5\x45\xfc\x19\xc4\x83\x69\x49\x07\x5e\x1c\xfb\x00\x4b\x3e\x32\x92\xac\x69\x24\xa6\xec\xdd\x22\x71\x64\x27\xf4\xb5\xe7\x6d\xb7\x36\x67\x82\xb0\xe8\x38\x7d\x0e\x44\xdf\x08\x07\x5c\x4e\x27\x22\x35\xa8\x2a\x5e\x76\xc7\x3f\x0a\xb9\xbd\x17\x17\x86\x05\xff\x6d\x72\x10\x99\xa6\x4a\x26\x0a\xed\xe9\x00\x83\xe5\x13\x60\xf5\x4d\xe1\x80\xac\xf2\x37\x34\xb5\xe0\xe4\x78\x86\xcb\x18\x50\xb8\x68\x54\x6f\xcd\xb0\x00\x2a\xb0\xae\xe7\x36\xcb\xea\x63\xdc\x15\x8d\x0a\x83\x92\x21\x7f\xd8\x2d\x51\x8b\xac\xa9\xa5\x59\xe1\xa5\xf9\x07\x03\x3e\x7d\x78\xf2\x56\xf0\xdc\x8e\xf2\x56\x29\xf3\x9d\x2c\xc4\xb5\x9b\x32\x73\x7e\x7f\x53\x37\xb0\x9e\x04\x80\xc3\x20\x2d\xb7\x87\x7b\xf4\x61\xbb\xc2\x38\x0c\x3c\x5a\xda\xf9\x4c\xe8\xb9\xaa\x44\x1d\xae\x4c\xe9\xed\xf6\x84\x81\xe3\x60\xc2\x71\xed\xef\x32\xfc\x3a\xee\xdf\x7a\x98\x96\x65\x86\x4b\xd9\xdd\xf9\x04\x2f\x04\xee\x74\x18\xd5\x95\x5c\xa7\xeb\xc0\xf0\x73\xe0\x12\x87\x2b\xb1\x03\x0a\xd5\x92\x97\xfc\x46\xe4\x4c\x98\x0c\xec\x81\x0d\x56\xd5\x4f\xf8\xfa\x4b\x93\xfd\x00\x9b\x3d\xad\x60\x98\x35\x0d\xe5\x41\x06\x9b\x00\xcf\x04\x96\xe4\x87\x95\x95\x36\x9d\xec\x60\xaf\x85\xb9\x57\xf5\xad\x13\x89\x39\x2f\xb4\x98\xc0\x0a\xa7\x98\x85\xc4\xd7\xb3\xd6\x88\xb1\xa8\x60\x94\x9f\xd2\x66\x1a\xc6\xa7\xa0\xbb\xab\x38\xe8\xae\x67\x68\x94\xc6\xa7\x41\x20\xdb\x38\x7e\x03\xc8\x45\x0a\xa4\x45\x31\x35\x4f\x10\x25\xb2\xce\xd0\x5d\x45\x0c\x99\xb2\x67\x1b\x07\xa0\x3b\x06\x72\xcb\xba\xe5\x4d\x13\xef\x4c\xda\x99\x01\x38\xe9\x77\x3d\x74\x01\x84\xad\xe0\xce\x10\xe6\x10\x66\x9f\xad\xc1\xcc\x12\x87\x4d\x7a\x41\x7b\x8d\x33\x13\x83\xa0\x47\xac\x35\xbf\xce\xb2\x76\x38\x58\xd7\xe2\x2c\x63\xa3\x72\xb4\xdf\x8f\x04\xfe\xbd\x30\xd9\x7b\x98\x43\x7b\x95\x01\x10\xf6\xfc\xea\x55\xec\x41\xbf\xe3\xb2\xa0\x6d\xbd\x6f\xa1\xfd\x08\xdf\xac\xfd\x72\xc3\x3a\xf9\x84\x04\x15\x21\xa9\xd9\xbf\x44\x66\xd0\xfb\x72\x23\x0c\x93\xe6\x1f\x3e\x7c\x94\x7e\xf2\xc6\x9c\xbf\x70\xf7\xee\x86\xeb\x4a\x64\x2e\xc8\x1f\xf6\x0a\x04\x1a\xc5\x90\xb8\x37\x54\x2d\x6f\x64\xc9\x0b\x7c\x63\xca\x7e\xae\x28\x80\x99\x10\xf1\x20\x1d\x12\x0d\xbe\x30\x8c\xc4\xff\x98\x0d\x18\x90\xf0\xc5\x58\x20\xd0\xdc\x21\x71\xe5\xc3\x5c\xf0\xab\x78\xfc\x0a\x9e\xb5\x86\x6f\x05\x1e\x6c\x49\x03\x00\x19\x46\x47\x3e\x90\xd5\x4c\x4a\x03\xbf\xc5\x78\x68\x3e\x13\x05\x9e\xfb\x0a\xa9\x0d\x3e\xd2\x09\x77\xe0\xf7\x35\xec\x09\xcf\x6b\x61\x9a\xba\x64\x33\x65\x01\x03\xa0\x29\x7b\x81\x36\xab\xc5\x9b\xc6\x42\xb1\xba\x93\xdc\xd9\xb3\x99\x2a\x0a\x01\x41\xcd\xff\xf0\xca\x91\x1e\x75\x87\x0d\xe6\x0e\xbd\x02\x5b\x52\x1b\xfc\x94\xfd\x68\xb1\x42\x24\x10\xea\xc0\x34\x02\x3c\xc2\xfe\x5f\x8d\x36\x44\xe6\x25\x97\xe0\x04\x26\x90\xf1\x54\xec\x2f\x08\x77\x10\xd3\x29\xfb\x5e\x98\xe8\xed\xc0\x62\x1a\xc9\xaa\x97\xb9\x6a\xca\x9c\x62\xa9\x3e\x69\xef\xa8\x5f\x0d\xc7\x2f\x03\x46\xdd\x10\x7a\x3d\x61\xcf\x33\x23\xef\xc4\x0b\xc1\xf3\x42\x96\xe2\x1a\x38\x3e\xb4\xa1\xda\x2f\xdc\xe2\xe6\x45\xa1\xee\x21\xb8\xbc\xf3\x35\x19\xfe\x4e\xae\x3b\x7b\x26\xd0\x61\xdb\x7d\x93\xb3\xa6\x94\xff\x6e\x88\x6f\x53\xf6\xcf\x46\xd4\x2b\xf0\xf7\x98\x58\x5f\x7b\xce\x3a\xdf\x8e\x16\x56\x58\x54\xdd\x4b\x71\xa7\xea\xa5\xf6\xd8\x02\x94\x21\xa2\xa0\xd5\x46\x36\x98\xbb\x3b\x8b\xcc\x73\x6f\x4a\xbb\xb5\x17\x1c\x17\x10\x8f\x22\x0a\x5e\x59\x31\x1f\xad\xae\x2b\x95\x77\x34\x34\xf2\xcd\x87\xa4\x8f\xe0\x15\xcc\x7a\xb6\x94\xc6\xf9\xc7\x6b\xb1\x54\x77\x7d\xac\xd9\xc0\x96\xe7\x8e\x5a\x2e\xe6\xbf\x97\x35\x71\xcc\x09\x1a\x7f\x70\x22\x05\x4b\xfe\xdf\x8d\xa8\x25\xf9\xf2\x20\x5f\x21\x70\x2c\xb0\xaa\xa9\x14\x25\x63\x48\x55\x4e\xd9\xf3\x3c\x67\x9c\xdd\x5b\x45\x35\x61\xd9\x42\x64\xb7\x4c\xce\x3d\x0b\xa4\x76\xb7\x2f\x53\x7f\xff\x0d\x66\x34\x1d\x3c\x27\xc0\x65\x7b\x10\x81\x1f\x20\x5b\x45\x2e\x85\x36\x7c\x09\xd9\x00\x6a\x06\xf9\x03\x39\x4a\x03\x8c\x12\x2f\x3b\xaf\x62\x3c\x04\x6b\x79\xde\x89\xd2\x38\x19\xf4\x72\xe7\xb7\x13\x3f\x91\x58\x3c\xdb\x30\x31\xc6\xde\xaa\x99\x43\x88\x03\x8a\xef\x38\x59\x18\x5c\x98\x8f\x63\x51\x46\xbb\x30\xa5\x74\x64\x0b\x5e\xde\xe0\x2f\x77\xbc\x68\xfc\xea\xfa\x11\x46\x05\xa0\x6b\x46\x2e\xc5\x3d\x7d\xe6\x1e\xa3\xb8\xf5\x8c\xbd\x35\x23\x18\x9b\x89\x05\xbf\x93\xaa\xd6\x5f\xff\x85\xb1\x73\x8b\xf1\x13\xbb\xe8\x9f\xc0\x18\x4f\x32\xb7\x9d\x76\x9e\xc0\xbe\xdb\xc3\x48\x2b\x8c\x32\x13\x4c\x94\x77\xb2\x56\xe5\x52\x94\x86\xdd\xf1\x5a\x5a\x23\x6a\x8c\x5e\x26\x63\xb9\xff\x7b\xa0\x00\x8d\xd0\xe3\x8e\xdb\x46\x31\x53\xd2\x8d\xa5\xb4\x95\x61\x81\xd7\x9f\x25\x83\x53\xe1\xdf\x3f\xfb\xea\xcb\x29\x7b\xce\xae\x69\x32\x19\x2f\x0a\xf0\xce\x2b\x1a\x1c\x7d\x2a\x41\x8f\x38\xce\xac\x85\xfa\xb7\xaf\xbe\xfc\x82\x19\x5e\xdf\x08\x38\x71\xe2\x6f\x17\x7f\xbb\x80\xd8\x34\x4e\x51\x67\xf7\x6d\x15\xe5\x12\xa6\x8a\x46\x53\x1e\x68\x99\xae\x49\x38\xc6\xd8\x5f\x02\x7a\x31\xf5\x00\x6e\xa0\x60\xb0\x68\xe9\xd4\x21\xb5\x1b\x15\x35\x88\xfd\x83\xcc\xa1\x74\x88\x61\x98\xba\xb1\x56\x9d\x66\xdf\xbd\x79\x73\xfd\xf2\xed\x2f\xaf\x2e\x5f\xbe\x77\xff\xfb\xc3\x9b\xeb\x77\x93\xbe\x07\x57\x6f\xde\xa6\x0f\xe0\x07\x8c\x0f\x4f\x7f\x7c\x6f\xe9\xf6\xfe\xdd\xe5\x55\xff\x37\xd1\xe3\xb7\x6f\xde\xbd\x19\x7e\xee\x2d\xb8\x41\x00\xcf\x5f\xbc\x78\x4b\xfe\xb3\xda\x2e\xde\xaa\x29\xc2\x2e\x81\x69\x71\xb8\x12\x0f\xb2\x03\x92\x25\xc5\x23\x83\x70\xc4\xfa\xe8\xf9\x0a\xcc\x60\xfb\xca\xa6\xcd\x0f\x36\x7f\x7a\xb7\xbb\x09\xb6\x36\xb1\xfb\x85\x74\x3b\xc9\x4c\xa0\xe1\x16\xa2\xed\x40\xb8\x49\x60\x5a\x50\xdd\x1e\xe3\x0d\xcd\xd7\x6f\xde\x59\xe4\xef\x59\x53\xc5\x1f\xdb\xf3\xa5\xa4\x53\x77\x3a\x74\xc7\xd5\xb2\x0b\x75\xb9\xd6\xf2\xa6\xa4\x1b\x17\x59\x8d\xa0\xac\xb5\x57\x39\xbc\xce\x5e\x5d\xed\xb5\xb9\xa0\x09\x41\xb7\xf0\xb1\x09\x9c\x24\xbf\x44\xd9\x06\x9a\x71\xcc\xfb\x03\x6a\xbc\xba\x62\x3c\xcf\xeb\x1e\xa7\xd3\x2e\x84\xb0\xb6\x92\x09\xe1\x50\x78\xb7\x00\x52\x63\x35\xd5\xbd\x98\x69\x95\xdd\x8a\xa1\x9b\x94\x98\x40\xce\x67\x36\x12\x22\xb2\x76\x5f\x13\x6d\xca\x7e\x75\x00\x93\x64\x4d\x65\x69\x5a\x4b\x61\x15\xd3\x07\x91\x79\x6c\xa2\x2b\xbb\xa0\xe0\x2a\xcb\x13\x97\x2d\xe4\xbe\xcb\xd1\xd9\x14\xc0\xb7\xd3\x88\x7c\xc8\xb4\x1d\x20\x09\xb0\xc3\x41\xb6\x70\x09\xae\xb1\x83\xd5\x0d\xc5\x55\x25\x84\x1b\xcf\x0b\x98\x0c\x1c\xdb\x3c\xa4\x34\xb4\xca\x72\x05\x57\xae\x1f\xe0\x14\x5c\x81\xdb\xba\x79\x7c\xbd\x7a\x10\xa6\xc4\xc9\x51\x87\x62\x03\x2b\xe4\x9d\x28\x85\xd6\x56\xc9\xcf\xc4\x84\x2c\x7b\x48\x00\x16\x65\x0e\xa1\x6d\x78\x6d\xd3\xd4\x83\x36\x6a\xad\x66\x89\x1f\xd9\x71\xea\xff\x94\xca\xfc\x9f\x56\x2c\x3c\x2a\xdc\x27\x0b\xc1\x0b\xb3\xf8\x5f\x74\x66\xda\xc1\x52\x3c\x0e\x74\xbc\x69\x01\x55\x65\x3a\x31\x76\xf6\xe4\x6c\xca\x7e\xa4\x97\x30\x4d\xc7\xbd\x08\x7c\xf2\x2f\x42\x6e\x34\x9c\xe2\xb9\x2c\x28\x3b\xa4\x05\xdc\xfb\xd7\x5d\xcc\x4c\xe9\xbd\xa0\x49\x44\xbc\xd3\x8a\x4b\x6b\xea\xfd\xaf\xa8\xd5\x78\x4d\xe7\x09\xfc\x1e\x86\x1c\xcf\xce\x42\x65\xe4\x7d\x9c\xb0\x52\x39\x7c\x0e\xc7\x4e\x50\x43\x9f\x64\x94\x89\xf1\xc4\x2c\x2b\x62\xf0\x27\xfb\xf2\x75\x04\x57\xc1\x6a\x69\xb4\xd0\xec\x4c\x40\x4d\x87\x28\x8a\x21\xa0\x24\x3c\x4e\x94\x12\xf9\x63\x0a\xc5\x7b\x99\x91\x7d\x8a\x4e\xab\xf4\x89\x0b\x26\x0b\x94\x63\xc4\x4d\x97\x70\x82\xfc\xbc\x38\x01\x33\x4d\x56\x31\xd4\x10\xc7\x61\xa6\xc9\xaa\xaf\xad\x6d\x4e\xbe\xb4\x93\x2c\xcb\x30\x27\x3a\x16\x58\xeb\x0a\xeb\x32\x60\xc9\x03\x17\x7e\xe8\x4f\x0e\xb8\x24\xc9\xb8\xc0\x55\x5d\xd7\xaa\xd6\x54\x33\xe6\xe9\x05\xb9\x40\xf5\xc4\x27\x3d\xd0\x00\xf4\xa1\xe5\x17\x42\xad\x44\xb9\x9f\x38\x24\xa2\x40\x2b\xbe\x5f\x1c\x9e\xfe\xed\xf0\xf2\xd0\xd2\xd5\x3b\xca\xc3\x3a\x2d\x9d\x6a\xe8\x48\x4f\x9e\x46\x4b\x3b\x34\x40\x2a\xc2\x8e\xe1\x8a\x61\x90\x4f\xcf\x23\x1b\x0b\x06\x8f\x44\xa3\x23\x19\x74\x71\xe3\xb4\x34\xa1\xe6\x53\x9e\xe0\xd2\x87\x94\xb5\x6e\x0a\x63\x8f\xa3\x1e\x55\x14\x07\xda\x17\x83\x37\x92\xc4\xe6\xde\xf9\xf6\x6f\x25\x9c\x9e\xd1\x71\xe7\xa8\x2b\xcb\xac\x16\xf6\x2c\x69\x19\x91\x8a\x90\x51\xec\xe9\x89\xf7\x83\x03\xca\x8b\xdf\x06\x92\x2d\xe0\x10\x7a\xa4\xeb\xbf\x1a\xdc\x04\xa2\xd2\x36\x4e\x42\xd6\x6f\x04\x96\x77\x21\xfe\x02\xcf\x70\x78\x43\x0b\x77\x84\xc9\x17\x2d\x11\xa2\x5a\x12\xb5\xbc\xb9\x11\x35\x10\xb6\x85\x95\x22\x83\xa1\x47\x3e\x36\xcb\x46\x8f\xed\x70\x22\xf9\x68\xa9\x94\x65\x53\x18\x59\x15\x9e\xe3\x9a\xfd\x55\x17\xea\xfe\xd3\x6d\x65\x06\x83\x04\x55\xa9\x8c\x2a\x65\xc6\xed\x49\x10\xe6\xcb\x75\xb4\x12\xa2\xbd\xf5\x4f\xf5\x72\x0c\xf5\x02\xd0\x5a\x44\x59\x36\xda\xf8\x50\x6a\xc6\x6f\xec\xe6\x85\xf3\x71\x00\x14\xcd\x25\x25\xce\x5c\xd5\x81\x32\xa2\xb4\x04\xcd\xa3\x4b\x16\x92\x60\x4b\x2b\xcd\x78\xb9\x96\x5a\xfe\xf8\x06\xe3\x4d\x7d\x0e\x31\xa6\x91\xe2\xd4\xfd\xd4\xd0\x0d\x7f\x27\xea\x15\x5c\xce\xd0\xea\x0c\x54\xd3\x13\xb6\x14\x1c\x62\x97\x9b\xca\x28\xf6\x85\x9b\xc7\x41\x17\x4f\x2d\x78\x2e\xe3\xd5\x03\xf2\x26\x4b\x69\x24\x2f\xac\x26\xe1\xab\xd1\x4b\xc4\x47\xde\x44\x00\xe3\x78\xef\x19\xde\x06\xaf\xa8\xd6\x13\x45\xb6\x45\x23\x61\xd5\x01\x08\xbf\x77\x3c\xdb\x4b\xcb\x62\xad\x26\x08\xa7\x9d\xcb\x9b\xa6\x0e\x6a\x3e\x1d\x36\xba\x56\xf3\xe8\x07\x13\x61\xca\x2e\x81\x29\xce\x6d\x7b\x8d\xf5\xf2\x2c\xd3\xac\x56\x56\xcb\x8a\xd7\x3e\x4e\x2a\x01\x9c\x4a\xbd\xcb\xac\x42\x1a\x60\x70\x52\x28\x0e\x18\x95\xd8\x8a\x21\x1c\x95\xd7\xdb\x9e\x89\x7b\x19\x0c\x44\xc6\xf4\x05\xc7\x6b\xe1\x7c\x16\x7e\xb6\x07\x66\x2c\x71\x71\x0d\x2a\x99\x2a\x35\xb8\xf0\x4d\x54\x0a\x81\xf2\xcd\x53\x0d\x3b\xe9\x71\xca\x47\xe9\xe3\x3c\x5f\x4d\xa2\xbf\x29\xd3\x2a\x52\x57\x91\xb2\x77\xee\xd6\x83\x1e\x89\xaf\x5d\x78\xdf\x25\x86\xf7\x4d\x2c\x12\xcf\xf5\xcf\x5a\xd4\xdf\x7c\xf9\xc5\x17\x9f\x7d\x3e\xc0\xbe\xf6\x77\x54\xfc\xc4\x45\xcc\x75\x02\xe7\x3d\xd4\xe4\x10\xd0\xb4\x4b\x48\xc0\xbb\x8d\xcc\x19\x8c\xbd\x57\x78\xda\xd9\x65\x9c\x8a\x91\x6c\x78\x01\x19\x05\x2f\xb3\xd9\x8a\x55\x5c\xc3\x26\x1b\x06\x77\x39\x50\x4d\xc9\xb8\x66\x4d\x59\xd5\xf2\x4e\x16\x22\xbf\x11\x90\x73\x59\xa7\x97\xc1\xb2\x64\xd7\x58\x9c\x49\xe4\xac\x5a\x40\x94\x44\x5a\xa2\xc2\x85\x48\xb9\xfb\x21\x0a\x93\xe2\x7a\x30\x52\xaa\x13\x91\xe8\x05\x44\xb3\x9f\x5f\xbd\x60\x4f\xd8\xf7\xaf\x5e\x6c\x53\xa0\xc2\x05\x73\xbe\xa7\x60\xce\xcd\xd2\x40\x93\xbe\x11\x39\x06\xaf\x4d\x77\x95\x07\x1f\x2d\x1b\x20\xae\x17\x85\x98\xe6\x37\x2e\x81\x06\x03\xe8\xf6\x13\x0b\xb7\xd4\xbb\x65\x55\xca\x74\xc4\xa5\xca\x85\x15\x0d\x2d\x0c\x5d\xca\xe5\x67\x67\xda\x4f\x95\x66\x8a\x8b\x3e\x7c\x45\x22\xc5\x35\x22\xbb\x83\x94\x50\xd9\x8a\x24\x98\xae\x47\x4a\x24\xc8\x83\x66\x1c\x9f\x9c\x93\x92\xf7\xee\xee\xe3\x0a\x46\xdd\x8a\xfe\xc5\x58\xdc\x43\x09\x49\x3f\x74\x8c\x52\x09\x05\x4c\x7a\x74\xc7\x7d\x2d\x0d\xdc\x60\xd6\x4a\x99\x39\x65\x28\xae\xc3\x75\xa7\x8b\x88\x54\xb5\x84\xfd\x9f\x04\x69\xcd\x14\x7c\x0c\x2c\x5e\xed\xff\x9a\x46\x39\x87\xd0\x92\xa2\x50\xf7\x64\xb8\x0e\xca\x0f\x06\xd0\x1f\x93\xc9\x80\x86\x97\xed\x97\x3a\xe3\x05\xe0\xb9\x25\x9b\xef\x13\x36\xb7\xa3\x84\x9f\x0f\x0c\x12\x73\xdb\x2a\x41\x8c\xca\xf2\xeb\x93\x09\xff\xe6\x68\xdd\x30\x22\x08\xc0\x6e\x1b\xc0\x4e\x17\xbf\x33\x44\x83\x28\x9a\xd9\xeb\x69\x78\x37\x44\xd5\xf4\xa1\xea\x79\x3d\x65\xcf\xd3\x6c\xc1\x8e\x1d\xb9\x96\xf8\xfe\xc6\x9a\xb3\x1b\x7b\x54\x81\x8d\xeb\xaf\x4f\x2f\x2e\x2e\x3e\xa5\xeb\x59\xca\xdb\xba\x18\xaa\xd5\x54\x37\xe5\x24\x29\x28\x86\xce\x3e\x4c\x6b\x1a\xbc\xef\xa2\xe7\x58\xce\x26\x35\xe0\x6a\x4e\xa2\xef\x11\xc2\xad\x6e\x2a\xa6\xf6\x8f\x6f\x2c\x72\x43\x9b\xe2\x88\xb8\x61\x47\x65\x8a\x09\x1d\xde\x11\x27\x4c\xd5\xbd\xc4\x3f\xa4\x46\x7c\xd9\x17\x83\x32\xb1\x74\xe2\xa5\x1e\xbe\xae\xff\x85\x5e\x65\x2f\xdd\x8b\x69\xd0\xa1\x35\xf8\x95\xc6\x14\xc1\x3b\x0b\x58\x43\xee\x1e\x2b\x05\xca\x95\xff\x75\x7f\x0b\xb7\x37\x8a\x66\xda\x3f\x31\x96\x8b\xb9\x2c\x93\xd8\xb6\xaa\x16\x77\x52\x35\xba\x58\xb9\x87\x03\x71\x39\x20\x4a\x40\x17\x50\x90\x3b\xc6\x4a\x78\xc2\x8e\x64\x84\x2f\x52\x41\x05\x2a\xf6\xe6\x8c\x6e\x66\xda\x48\xd3\x80\x0e\x43\xec\x31\x73\xaa\xb3\x84\xa0\xcc\xc6\x91\xf8\xd3\xaa\x43\xd8\x9e\xa5\x4e\x83\x0f\x97\x51\x89\xc3\xee\xbb\x51\x90\xe2\x7a\x16\x86\xaa\x47\x0f\xc6\xc6\xd3\x71\xcf\x8d\x78\x5a\x06\x86\xfa\xd6\x43\x6c\x1b\xcb\xac\x16\xa3\x9c\xa7\xe1\xa0\xcc\xfa\x45\x15\xcd\x52\x5c\x37\xb3\x8a\x9b\xc5\xcb\xf2\xce\x13\x7d\x62\x09\x0d\x95\x0f\x8f\xc6\xb0\x3b\x18\x9b\x36\x01\x1c\xeb\x37\x2d\x6f\xce\xb5\x51\x35\xbf\xd9\xc8\xa6\x9f\xf8\xad\x60\xe0\xf7\xe2\x49\xbc\x80\x83\x95\xf1\x12\x13\x69\x0d\x51\x9c\x97\x61\x2e\x4c\xcd\x87\x43\xdd\xb6\x08\x4d\xda\x87\xb0\x68\x1b\xcc\xb4\x2a\xa0\x44\xfb\x70\xd5\xcc\x61\x0a\x83\x0f\x73\x1b\x02\x77\xc7\x4c\x69\xfe\xdb\x75\xa1\xee\x0f\x41\x79\x72\xe4\x0d\x52\xdf\xed\x81\x3d\x62\x8f\x05\x16\x12\x1c\xa5\x06\x3b\xa1\xe8\xa9\xcb\x76\x4c\xe6\xcc\x78\x76\x6b\x64\x76\x3b\x14\xab\x73\x68\xc6\xf8\xf1\x1e\x29\x53\x02\x7e\x50\xcb\xe6\xb4\x1c\xc1\xea\x98\xf6\x98\xb5\x3d\x3b\xa8\xda\xb6\xa5\xbe\x85\x60\xa7\x4e\x60\x81\x23\x69\xf0\xd2\xf6\xb4\xff\xe4\x17\x57\x13\x12\x8a\xc7\x76\x34\xa7\xd3\x45\x50\x2c\xcb\xa7\xcc\xba\x14\x39\xa3\x3c\x32\x78\x96\x7c\x3a\xfd\x1f\x03\x81\x82\xee\x77\xf1\xa1\xaa\x19\xdd\x47\xc5\xee\x0e\x67\x33\x3f\x9b\xfe\x8f\x01\xf2\xcc\x55\xcd\x92\x2f\x03\xc1\x18\xfb\x6c\xfa\x3f\x26\xca\x11\x4a\x74\x21\xf8\x96\xa3\xc1\xa4\x2e\xcf\x0c\xf4\x45\x90\x35\x45\x3e\xa3\xd0\xb2\xac\x10\xbc\x6c\xaa\x4e\x5e\xcf\x71\x98\x8e\x6e\x61\x2c\xef\x8d\x09\xf5\x70\x56\xde\x5a\x00\xee\x12\x06\xb9\xea\xda\x7d\x5b\x1c\x73\xcc\x5a\xaa\x1c\x3d\xed\x79\x38\x42\x86\xae\x0f\x69\xd0\xdb\x0e\x32\xf3\xcb\x38\x8c\xd6\x60\x43\xb7\xcd\xfd\x18\x1d\x62\x51\x5a\xfb\x07\x92\x48\xf4\xc4\x11\x10\xfe\x44\x7e\x5c\x63\xba\x3b\x55\x4d\xa6\x04\xd2\x01\xc6\x00\x79\x4a\x95\x8b\xdf\xd9\x4b\x00\x18\x27\xfd\x58\x88\xb3\x95\xcb\x72\xd6\xa1\x9c\x95\x1b\x00\x6d\xf1\x99\x6a\x0c\xc6\x1f\xc7\x89\xf6\x65\xee\x57\xc1\x16\x66\xdd\x84\x2d\xbd\xba\xf4\xdd\x37\xec\x74\x89\xda\x94\x00\x14\xa5\x26\xc3\xc4\x29\xb9\xaa\x95\x37\x73\x2b\xcb\xfc\x1b\xfb\xb1\x47\x5c\x35\x75\x26\xa0\x8a\xf2\x42\x04\x3a\x51\xfe\x1e\xad\x36\x24\x6c\x30\xc8\x67\x22\xa9\xfd\xd4\x1e\x3a\x1d\x76\xfd\x90\x00\xd4\x67\xf4\x76\x07\x1d\x18\xf0\x5b\x65\x16\xfd\x5c\x0d\xf7\x52\x5a\x94\x4e\x26\xba\x45\x0f\x22\x5e\x60\x84\xf4\x66\xfb\xd4\xca\xc4\x13\x84\xd7\x27\x7d\x2f\xef\x24\x35\x86\x79\xa7\x0a\xe7\x5a\x2b\xe4\x52\x0e\x86\xcf\x46\x92\xf6\x5a\xbd\xc4\x12\x2b\xef\xb8\x2c\x29\xc1\xbe\x66\x3f\xb9\x1b\x7e\x08\xb4\xfd\xed\x5a\xd4\x92\x17\xbf\x33\x61\x47\xa2\xdb\x3c\xfb\x00\xf6\xe3\xa5\x2c\xc3\xb8\x2e\x6f\xf0\xb7\x17\x52\xd7\x4d\x65\xe4\xdd\xe6\x72\xca\x76\xb3\x87\x90\x82\x73\x12\x5c\x51\xf2\x5a\x2a\x4a\xfb\x69\x83\x9e\xb8\x74\xa2\xc0\x21\x40\x8b\x4e\xeb\x5c\xb3\x8a\xae\x01\xc3\xa7\x78\xc1\x08\x24\xe9\x2c\xf9\x2f\x07\xe8\x6d\x35\x44\x97\xde\x40\xa5\x49\x42\x76\xb8\xed\xb4\x3f\x63\x2e\x1e\x2f\x76\x25\xfa\xb5\x2c\x6f\x90\xe4\x81\xe2\x00\xd2\x9f\x95\x60\x94\xcc\x92\xb1\xd0\x38\x6b\x3b\xfe\x16\xb4\x4e\x12\xe2\x5b\xf4\xb1\x9a\xc3\x69\x93\x1c\xcb\x83\xc1\x80\x22\x67\xf6\x6c\xe8\x43\xe0\xdc\x65\x24\x51\xdd\x25\xf0\x21\x72\x50\x0b\x09\x33\x12\x5d\x13\xa2\x16\x17\x44\x99\x77\xcf\x0e\xdb\x31\x01\xc3\xc5\xff\xf9\xe6\x7a\x33\xa5\x41\x7e\x5f\x7e\x30\xa2\xcc\x45\xce\xd2\xf8\xf1\x6b\x61\x2c\x10\x76\x59\x70\x9d\x54\xe0\x22\xeb\x4f\x95\xf8\x1e\x4a\xb9\xab\x65\x55\x0b\x52\x23\xae\x1f\x12\xa5\x42\xdb\xe5\x06\x6a\x67\x29\x96\xaa\xa6\x9c\x86\xaa\xd9\xfa\x18\x7d\x79\xf5\x33\x26\x8c\x20\x18\x1a\x25\x1a\xa4\x93\x52\x81\x31\x2a\xfc\x4e\xd8\xd9\xd0\x64\xb0\x06\xc4\x95\xca\xff\xf9\xe6\xfa\xfb\x86\xd7\xbc\x34\x62\x54\xb9\x66\x20\xfb\xe6\x9c\x38\xbf\x85\x3e\x71\xf4\xd0\x3d\x2c\xf2\x1d\xb5\x86\xdb\x78\xc5\xbc\xaa\xc5\xb5\x7d\xdb\xa5\xbf\xf1\xa2\xf0\x10\x40\x8d\xde\xca\xa2\x08\x37\x27\x5b\xa6\xb7\x55\xf1\x55\xb7\x36\x71\xd0\x37\x98\x7f\x67\xb8\xc7\x61\x82\xa2\xa6\xdb\x86\xb7\x22\x13\xf2\x8e\x54\xcb\x5c\x8a\x22\xde\xed\xa2\xcb\xf3\x56\xa3\x2f\x04\x05\x9d\x17\x7d\xcd\x17\x57\xd6\x8d\x46\x55\x21\x1d\x35\x64\xca\x4d\x13\x83\x27\x49\x7f\x0c\x23\x28\x75\x1b\x67\xca\x46\xc9\xe9\xfe\x42\xde\x27\x4c\x26\x5f\x4d\xd9\xb7\xa1\x2f\x18\xdd\xdb\xfb\xcc\xda\x4e\xab\xb2\xb8\x24\x01\x25\xfd\xdd\x53\xc7\x0f\xf2\xdb\xf7\x63\xdb\xca\x7b\xe2\xc8\x47\x70\xa1\x25\xc2\x00\x97\xc2\x60\x30\x49\xcc\x80\x82\x68\x1d\x67\x43\x92\x78\xd7\x44\x7f\x17\x51\x12\x91\x6a\xac\x28\xd7\xe2\xbd\x1d\xb6\xad\x43\x9e\xe7\x4b\xa9\xc1\x76\xbc\x17\x33\x8b\xd2\x04\xeb\x04\x2c\x1b\x83\xf7\x36\xf4\x73\x7b\x0b\xb5\xe2\xca\x2b\x79\xbe\xe4\x56\x1d\x88\x7a\xf5\x7b\x00\xf5\x2b\x7e\xc2\x7e\x0b\xf7\xa3\x5f\x5f\x62\xb2\xa2\x7d\xa7\xfc\x1d\x86\x70\xda\xbc\x33\x92\x13\x7c\xa8\xe2\x32\x4a\xb8\x9f\x5e\x74\xa0\x78\xfe\x80\xca\xd5\x70\xa9\x95\xa4\xb5\x4d\xd9\x73\x63\xc4\xb2\x32\xae\xc6\x10\x4c\xdb\x12\xb7\x1f\x42\xd0\x7c\x3e\xdf\xf6\x1f\x00\x14\x6e\x58\x5c\x9c\x01\x7e\xea\x6a\xbc\xc4\x9f\xbb\x4d\xda\xb2\x1f\x52\xad\x69\x78\x88\xf7\x71\xb5\x26\xa8\x4e\xc8\x3f\x30\xf9\x1a\xfe\x9d\x08\x20\xcc\x12\xfa\x0e\x84\x8f\x71\x9f\xd9\x0e\xf3\x50\x31\x07\x65\x34\x2a\x40\x81\x84\xea\x07\xe4\xe6\xe0\x0a\xa0\x75\xe7\x40\xf7\x53\x83\xf3\xa0\x0a\xe0\x6e\x1e\x23\xf6\x3f\x5e\x49\x2f\x63\x4f\x08\xaf\xb1\x42\x4c\x8d\xf3\x4e\x22\xc6\x3d\x63\xed\x24\xc8\x5d\x38\x7f\x00\x51\xa6\x5f\x63\x51\xce\x45\x29\x0f\x25\xc9\x5d\x29\x46\x39\xdc\x47\x92\xfb\xa7\x10\x8e\x60\x24\xc9\x34\x8d\xe3\x09\x32\x15\xe8\x69\xeb\xb7\x83\xca\x71\x45\x64\x7d\x02\x83\x85\x96\x9b\x1d\xa5\x3a\x5e\xa0\xdf\x8a\x1b\x09\xd9\xe9\x11\x14\xde\x9e\x5d\xca\x95\xa4\x4e\x42\x2c\x7e\x46\xe1\x35\x7b\x55\x15\x2b\x67\x47\x10\x93\x42\x0c\x05\xd6\x34\xdf\xc0\xc4\x18\xaa\xe7\x22\x2a\xa3\x48\x55\xc5\x15\x8b\x1c\xa6\x46\xad\x1f\x1f\x29\x86\x01\xc2\x5b\x60\x42\x37\xee\x1d\x0c\x8e\x2e\x4f\x5d\x35\x73\x12\x89\xea\xd1\x6e\x3b\xc9\x54\x04\xe7\x91\x4a\x55\x2e\xca\x55\x04\x73\x17\x99\x42\x79\x0a\x21\x1f\x5b\xc9\x54\x7b\xfc\xe3\x49\x14\x8c\xc4\x8d\xe1\x59\xfb\x4e\x6a\x3f\x19\x4a\x4f\xa2\xdc\x97\x80\xf5\xa3\x51\x74\xde\x68\xa9\x29\x37\xc9\x0a\x5a\xf0\xa0\xd2\x21\x30\xa7\xb4\xbb\x89\x73\x3a\x28\x3c\x6f\x9d\x69\x1a\x9d\xe9\x66\x76\xee\x4e\x7d\x7e\x03\x81\x83\x0e\xbd\x10\x36\x99\x23\xef\x11\x40\x13\x6a\x93\xe6\xcf\xe5\x51\x01\xb3\xde\x92\xbd\x47\x63\x4e\x2f\x22\xe0\x97\x8b\x8a\xcd\xf9\xca\x45\x47\x62\x5e\x6b\x4c\xbf\x88\xfc\xb8\x6a\xde\x46\x54\xa7\x4c\x44\xfa\x75\x91\x16\xf4\x9d\x4b\x43\xc2\x6f\x4f\xcd\x6c\x67\x8d\x9c\x84\xa3\x15\x39\x8f\x91\xde\x4b\x5e\x79\xfa\x1e\x9a\x7d\xf6\x25\xa3\xbb\x03\x52\x9f\xee\x0e\x7b\xa0\xaf\x5b\xa6\x96\x55\x21\x79\x49\x1e\xff\xe4\x43\x0d\x61\x61\xc8\x43\xac\x50\xc4\xfc\xeb\xc1\x81\x9b\x7e\x42\xd5\xde\x52\xd0\x2d\xfe\xb2\xe7\x65\x9f\x42\x76\x20\xc9\x89\xc2\x21\xf5\x8e\xc7\x1a\x7f\xc1\xcb\x9b\x76\x7e\x53\xf4\x02\x39\x20\x21\x19\x68\xe2\x5b\xf8\xb8\xca\x51\x9e\xec\xe3\xb0\x69\x4d\xc1\xcf\x90\xb2\x64\xec\xb8\x0b\x69\x04\x55\x5f\xb1\x62\xa4\x2b\x9e\x09\x36\xe3\x3a\xf8\x1a\x1c\x6a\xe1\x71\xa7\xd6\x15\xc5\xad\x9e\x5a\xc3\x41\x40\x8c\xec\xa9\x92\x73\xb0\x85\x40\x6b\x2d\xdf\x5e\xde\x03\x47\x63\xad\x34\x38\x01\x6f\x25\xb4\x4e\x72\x9e\x93\xc3\x9f\x26\x27\x2c\xe7\x26\x3d\x99\x36\x5a\xa8\x52\xd5\x4e\x6c\x8f\xc5\x86\x64\x90\x0d\x2c\xf8\x19\x63\x15\x52\xfa\xdf\x73\xab\x55\xbe\xf0\x49\x75\xe4\x93\x07\x6d\x03\x46\x24\x9a\x51\x10\x79\x46\x6e\x3d\xbf\xee\x1c\x20\xd7\x09\x62\x46\x9d\x4d\xa1\x8d\x03\xe1\xa4\x7d\x57\x98\x06\xca\x44\x41\x53\x15\x8a\xbb\x8a\x8e\x96\x78\x98\x8e\x32\x11\xe6\xf2\x86\x59\x75\x8a\x81\x63\x3c\x4b\x06\x98\xb2\xb7\xce\xb5\x8e\xa5\x18\x69\xfe\x74\xd1\x10\x1c\x90\xae\x94\x4b\xa2\x41\xa4\x66\x85\xd0\xda\xce\xbf\x8c\x66\xde\x83\xa7\xd4\x94\x8d\xeb\x87\xf3\x69\x8f\xd6\x40\x6e\x0d\xdb\xfd\x58\xde\x94\xaa\x16\x6d\x6c\xad\x0d\x1c\x7d\xba\x19\xdb\x28\xe7\xf1\xaf\xcb\x26\x5b\xb0\x42\x95\x37\xd8\xc9\x34\x55\x44\x96\x99\x2c\xa7\x6d\xe3\xd3\x63\x2a\x1d\xa9\x33\x75\x27\xea\x15\xcb\x55\xd6\x50\xe8\xd7\x51\x04\x5c\x96\x59\xd1\xe4\x61\x8a\xc1\xac\x90\x65\x0f\x1a\x9b\xea\x7a\xbd\x5b\x88\xb0\xdd\xd6\xa0\x93\xe8\x30\x84\xd7\x0d\x50\xd2\xf8\xa6\x56\x4d\xe5\xc2\x06\xa5\x0e\x9d\xf0\x2c\xb9\xf0\x72\xb3\x3b\xf2\x74\x23\xec\x27\x77\x4f\x03\xf8\x27\x77\xa2\xd6\x6e\xbf\xc2\x80\xa1\xee\x50\x83\xc3\x38\xc7\x01\x51\xa5\xe5\xc2\x71\x7b\x63\x38\x0a\xf6\xbf\xd7\x32\xd1\x00\x81\x64\xfc\x27\x1b\xa6\x33\x44\x8a\xe3\x09\x9e\xaa\x73\x51\x8b\x9c\x08\x70\xbc\xed\x8d\xfc\x0e\xc1\xac\xdb\xde\xa7\xd3\x6f\xcb\xe1\xc5\xcb\xbd\x0a\xae\xd0\x60\xdd\x45\x1e\x45\xb2\xcf\x4a\xd7\x49\x29\xb7\x0a\x8a\xe5\xdc\x70\x76\x2b\x56\xa9\xa2\xb3\xe8\xf1\x02\x43\x7c\x16\xd0\x07\xdb\x67\x3e\xdd\x8a\xd5\x24\x9c\x92\x4b\x65\x16\xd4\x00\xd9\x41\x8c\x80\xd9\x7f\xf2\x3c\x0f\xc5\xcc\xe7\xb2\xd6\xc6\x4f\x43\x6a\xef\xd5\x8c\x2d\xce\x74\x2b\xf6\x7a\xfb\x1f\x58\xe9\xf9\x56\xac\xa2\x30\x09\x00\xee\x4e\xf4\xfe\xd5\x23\x4a\x8b\xe3\x62\x6a\x21\x1c\x5b\x66\x5a\xf6\xc8\x6e\x76\x11\x02\xd3\x5d\xfb\x66\xe8\x6a\xa1\x3d\x6c\xe2\xa1\x6d\x3d\x73\x1c\x39\xfe\x65\xc3\x00\x4d\xd0\x35\x2d\xe7\x73\x51\x43\x50\x8e\x51\x76\x51\x93\x4a\x3c\x31\x7f\xd6\xe2\xb2\x27\xf7\xda\xe7\x68\xe6\xed\x59\x6c\xbb\x0e\x87\x2f\x5c\x4f\x11\xa8\x35\xc6\x30\xc6\x9b\xde\x3d\x85\xc2\xba\x09\xa6\xd1\xb5\x73\xcf\x29\x3c\x76\xb2\xad\x01\x4f\xdd\xe1\xef\x9e\x59\xf8\x78\xcb\x9a\x8c\xd1\x5e\xf9\xd5\x20\x50\xba\x85\x29\xc5\x3d\xde\x8a\xc3\x7c\xc1\xee\x43\x91\xac\x7c\xed\x65\x7f\xae\xc6\x30\xd8\xb4\xad\xfe\xc3\x48\x66\x55\x37\x25\x7a\xb7\x4e\x2e\x88\x34\xf4\x58\xb9\xeb\x5e\x11\x07\xed\x0e\x74\x47\x8f\x00\x8e\x44\xa6\xfc\xd4\x7f\x4e\xae\xe7\x35\x02\x41\x6c\xd4\xd9\x42\x2c\x39\x55\x78\x40\x8b\x4c\x87\xd6\x44\x14\x15\x67\x77\x27\x2c\x32\x62\xb5\x7e\xb2\x95\x38\xec\x12\xe5\xd5\x19\xf8\x1f\xb4\xed\x00\xda\x34\x8c\xb3\x02\x7d\x28\xe3\x92\xb7\x6f\xd9\xd0\x72\x07\x21\xb3\x56\xb9\xfb\xb0\xef\x23\xbc\x9a\xa2\x14\x10\xbf\x99\x1d\x53\xc2\x3c\x11\xa9\xb9\xd9\xf1\xc5\xca\x79\x88\xd0\x81\xee\xdb\x1f\x63\xf1\x0b\x8f\xd3\xee\xf6\x4c\x64\x3e\x94\xad\xfe\x93\x56\x23\xa8\x5c\x0f\x9f\xd5\x2b\x95\x23\x93\xd3\xef\x5a\x16\xc2\x42\xb0\x77\x54\x5c\x5f\xaa\x92\xaa\x5e\x5e\x85\x2e\x8e\xe1\x08\x0f\x73\x3b\xea\x06\x16\x7c\x73\x99\x2a\x4d\xad\x8a\x90\xd7\x8a\x8e\xa0\x5e\x33\x0f\x33\x47\x71\xb9\x1d\x8b\xdd\x94\x85\xe0\xdc\x91\xc4\x7d\xc8\xf4\xc4\x50\xd7\xd8\xa1\xdb\x6f\x8c\x12\x86\x63\x85\x21\xd5\x31\x34\x20\x7a\x7f\xcb\xd5\xe6\xe1\x62\xa2\xf4\x5f\x2b\x47\x15\x9b\xd7\x21\x4c\xc6\xa5\xbf\x0d\x6a\x85\xff\x46\xa9\xe2\x83\x17\xe6\x6b\x42\x2f\x52\x85\x75\x3c\xc9\x82\xdc\x96\xac\x50\x5a\xb4\x9b\xbb\x1e\x4c\x44\x9a\x32\x53\x65\x0e\x9a\x1c\x6a\x67\xd5\x02\x26\x1d\x08\x67\x05\x38\xc2\xc3\xd3\x6a\x6b\xab\x87\xf6\x89\x18\x96\x6b\xa0\x5b\xe6\xbe\xbd\xfb\xe5\x73\x36\x6b\xca\x9c\x5a\x06\x6a\x45\x1b\x8a\xa1\x16\x48\x96\x09\x18\x48\x16\xc4\x23\xc2\x15\x5e\xa6\x5c\x0a\xcc\x44\x6f\x13\x35\x04\x37\x1c\xc7\xcb\xc7\x6f\x6e\x6a\x71\xc3\x8d\xaa\xcf\x29\xdf\x5a\x9f\x9b\x85\x38\xd7\x7c\x59\x15\xc2\xf2\x0c\xc3\xcf\x46\xf0\xd3\x43\x62\xd7\xa1\x81\x12\x2d\x65\x97\xcb\x6d\xe7\xf8\x74\xfa\xf4\x2b\x76\x0d\xf0\xd1\xf8\xba\x7a\x05\x95\xf6\x45\x1d\x25\x40\x62\xff\x5b\x13\x43\x1d\xdf\xa5\x17\xf6\xc8\xd6\x04\x00\x7d\xcc\x4f\x00\x04\xf0\x16\x60\x59\x41\xea\x08\xdc\xbd\x92\x1b\x0c\x9e\x42\x81\x33\xb8\xa5\x26\xc7\x78\x17\x9f\x27\xcf\xaf\x5e\x9d\x23\xde\x1d\x66\xf4\xb4\xb2\x49\x98\x11\xa8\xde\xe6\xc7\x25\xda\x0f\x6f\x9d\xe1\xf2\x22\x18\x2e\x97\xaa\x74\x26\xfc\xaf\x6e\xc5\x65\xf0\x9b\x61\x4b\xf9\x21\xb2\xf0\x0b\xa9\x47\x78\xaf\x70\x28\x37\x52\x80\xbe\x71\x3d\xc6\x55\x1b\x22\x1e\x3b\x5c\xe0\x26\x82\x2d\xd4\x52\xdd\x88\x52\xa8\x46\x63\x88\x92\x9a\xb3\xcb\xb7\xa3\x15\x33\x27\x70\xc9\x1d\x12\xc5\x56\x0e\xda\x76\xad\xfe\x4f\xed\x17\xc9\xf2\xe7\xc6\xf2\x88\x5d\x86\xae\x1c\x6b\xac\x45\xca\xdc\x71\xdb\xfe\xdd\xb3\xce\xa1\xa4\x17\xfe\xb3\x64\x37\xf0\x21\x5a\xed\xc3\x13\x22\x6a\xdf\xff\x07\x65\x11\x69\xe3\xae\x8a\x60\xbd\xbb\x76\x18\xb0\x3b\x74\x8e\x5e\x38\xd2\xb6\x9a\x20\xab\xf3\xf7\x81\xb8\xef\x07\x14\xc3\x4e\x82\x88\x56\xc5\xb6\xbe\x89\x63\x09\x22\x2c\xf6\xcb\xb7\xf6\x6c\x69\x14\xfc\xe3\xd9\x29\xc5\xef\xee\xe9\xa0\xa3\x43\x63\x04\x1c\xcf\xed\x4e\x01\x5c\x44\x76\x53\x36\xe2\xc9\x59\x3a\xc1\xc6\x41\xdb\xb2\x2a\x92\x89\x5f\xe1\xf0\xbb\x9e\x53\x1b\x3e\xc6\xde\x45\x5d\x01\x8a\x97\xe3\x38\xf3\xce\xaf\xd0\xe1\x19\x27\xeb\x13\x47\x96\x2e\xb2\x86\x48\x41\xf6\x17\x35\x58\xf2\x21\x02\x90\x6f\xb7\x8a\x4d\x3b\xca\x52\xda\x85\x69\x30\xd6\x36\x7c\x1a\x1b\x0b\x30\x48\xeb\xa0\x3d\xd6\x33\xeb\x5a\xda\xfd\x73\x18\x8e\xab\xf5\xf3\x04\x8d\xe4\xf2\x66\x04\xdb\xf0\x36\x48\xd5\xb7\x7a\x74\x22\x83\x35\x0e\xc4\x07\x23\x28\xe5\xb1\x90\xee\x74\x8c\x05\x12\x18\x67\x35\x2f\x73\xb5\x5c\xb7\x2c\x51\xf8\x10\xe2\x06\x75\x4f\x16\xb6\xeb\xbe\xc5\x24\xdd\x4e\xf8\x2b\xe1\x38\xac\x24\xb1\xd1\xb7\x6a\xc3\x94\xca\x01\xa0\xf3\xde\xa1\xf3\x3e\xc2\x7c\x0b\xc1\xa0\xe4\x81\x38\x4e\xe9\x11\x48\xc9\x0d\xd6\x55\xf3\x91\x81\x4f\x5c\xac\xe0\xfa\xfb\x7d\xd6\x37\x9d\x2d\x25\x67\x9d\x9e\x4e\xe2\x90\x79\x9e\xc4\xfd\x54\x7e\xf9\x4b\xa3\xfb\xf0\xc0\xf0\x69\xef\x44\x48\x50\x8c\x6c\x7b\x27\x18\x77\x12\xfa\xc7\x39\x0b\x42\x37\x33\x2d\xfe\xdd\x08\x48\x9d\xe3\xe3\xd2\xc2\x8e\x20\x2e\xbb\x98\x88\x47\x90\x0f\x0a\xaa\x1f\xa3\xf2\xf7\xd7\x1b\x13\xa7\x34\x9e\x5e\x60\x3c\xb9\xc8\xd7\x0c\xac\xfd\x2d\x93\x33\xdf\x96\xae\x36\x42\xab\x61\xd1\x06\xdb\x2d\x6d\xd9\x49\xee\xbf\x35\xe3\x76\xbb\x88\xae\xc7\x93\xdd\x49\x1e\xa5\x77\xc4\x0d\x46\xd1\x89\xb9\x63\x73\xd1\x11\x98\x3e\x8c\xec\x6e\xe3\x77\xdc\x5b\x82\x7b\xa6\x4f\x83\x43\xe2\x63\x92\x10\x09\x06\x27\x9d\x18\x0e\xa6\xad\xbc\xab\x81\x46\xf6\x07\x90\xcb\xb7\xd0\x5b\x92\x58\x0f\xcf\xa8\xac\x2c\xcf\xad\xb5\xdb\x94\x06\x9b\xb0\xf8\xa7\x52\xbb\x2b\x89\x70\x8a\xa1\x1b\x54\x0b\xec\x2d\xa6\x64\xd0\xdb\x74\xcb\x9a\xe7\xfe\x73\x3b\x5f\xf7\x7e\xb8\x01\x49\x87\x0b\xb7\x23\x90\x13\x47\xde\x4c\xec\x3f\xa1\x8a\x14\x59\x6d\xf8\xaa\x2b\x43\x9b\xce\xce\x07\x92\x21\x77\xc5\x7f\x02\x11\xa2\x13\x8a\x8b\xfb\x58\xc3\xea\x3d\x43\x41\xbe\x13\xd6\x8e\x85\x38\x87\x89\x0b\x77\xa8\xa4\x57\x83\x9a\xc2\x1c\xb0\x33\xf5\xf0\xf3\xe1\x30\x08\x8d\x9f\x0a\xe7\x6b\x11\x2b\xe8\xec\x9d\x81\x38\x0e\x91\x69\xdd\x10\xd1\x59\xb6\x8e\xda\x6d\x9f\x50\xb1\xbc\xa9\x44\x69\x37\x8b\xab\x66\x56\x48\xbd\xb0\x86\x94\xaa\xb0\xc9\x64\x79\x33\xfe\xfe\x36\x9d\x3d\x01\x73\xb0\xd7\x8b\x07\x66\x42\xe9\x58\x0e\x50\x91\x54\x22\xc3\xf4\x53\x55\x0a\xef\xdb\xb9\x11\x46\x53\xc2\x6e\xee\xd2\x1a\x66\x94\x24\x3a\x3e\x3a\x7e\xe3\x05\x99\x6f\x77\x40\xe3\xea\xa9\xa3\x94\x5b\xc2\x7e\xfb\xf1\x77\x57\x38\x69\x2a\x0a\xb3\x76\x83\x8b\xb2\x34\x7a\x6e\x76\x5b\xd7\xb7\x50\x1d\x19\x8e\x60\xd1\xcd\x5c\x07\xad\x0e\x4a\xee\x12\xd6\xb5\x8b\x25\x48\x6e\x57\x8e\x80\xf8\x32\xef\xa5\x72\x71\x68\xd4\x53\x77\x97\x23\x1d\x91\xe1\xbd\xaa\x44\xc9\x2b\xb9\xb5\xfc\x39\xa4\x6a\x10\xb7\xa3\x4a\x1e\x92\x06\xaf\xc5\x03\xf7\xd6\xc8\x1d\xe2\x74\x4c\x31\xfb\xc7\x21\xc5\xec\x2d\xa0\x1b\x89\x0d\xc6\x90\xd1\x50\x4e\x94\xd6\xe0\x78\x27\x39\xe3\x78\x22\xf8\xc7\x7a\x41\xa3\x03\x04\x1c\x28\xe6\xd6\xfc\xa2\x66\x00\x16\x81\x07\x11\x23\x20\xef\x87\x73\xb8\x13\xae\xef\xc4\x79\x53\xde\x96\xea\xbe\x3c\xa7\xbb\x68\x6e\xa0\x7c\xf2\x51\xc5\x0b\x2d\x20\xcb\xa5\xcb\xb7\x2f\x18\x61\x02\x05\xd8\x11\x17\x16\x70\x89\x6e\xb5\x2d\x5a\x87\x13\xb0\x41\x0a\xf4\x5c\xc2\xdb\x91\x87\x6e\xf1\xf0\xea\x99\xbb\x5e\xce\x9d\x81\x27\xde\x0a\xbf\x6d\x66\x22\x33\xc5\x3f\xe8\xd0\x71\xae\x65\x1e\x32\xf0\x5c\x34\x3f\xcf\x32\x51\x19\x4f\x08\x2c\xde\x68\x64\x1c\x41\x4c\x70\x28\x90\xb2\x2a\xb8\x24\x7b\x3e\x2e\xdf\x0b\x8d\x55\xfb\x84\xf8\xbf\x5f\xbd\x7e\xf1\x18\xe5\x4e\x96\x4c\x2c\x67\x22\x77\x61\x10\x78\xba\x7b\x14\x62\x08\xd9\x9c\x1e\x3b\x77\x9d\x7a\x3a\x49\xec\x0e\xbe\xb3\x30\xa2\x9e\x93\xfc\x41\x84\x91\x9b\xbe\xb9\x06\xa8\x76\xa7\x6d\x42\xce\x09\xde\xfc\x0b\xc8\x4a\xc1\x6a\x23\x0f\x26\xb6\x11\x61\x50\x25\x9c\x50\x2e\xfb\x11\x38\x9c\xf8\x25\x69\xb4\x04\x9c\x7a\x9c\xb8\xac\x47\x35\x0f\xa9\x11\xbc\xae\xf9\x0a\x4f\xb5\x55\x2d\x97\xd2\xc8\x3b\x31\x18\xe2\x30\x20\x8f\xa9\x51\x47\x71\x7e\x50\x83\x30\x08\xc3\x64\xbc\x98\x56\x5c\xeb\x34\x5c\xaf\x15\x33\x41\xad\x45\x3a\x62\x9c\x5c\xd8\xfb\xca\x85\xe1\x39\xde\xb1\xaf\x1b\x9a\xa2\x0c\x40\xe0\xfd\x70\x9d\xd5\x91\xac\x0c\xa4\x68\xb4\x3a\xe8\x61\xaf\xb6\x5e\xb3\xe4\xfc\x77\xae\x06\xe1\xe0\xa7\xdd\x05\x19\x0f\x49\x2b\xac\x7b\x39\xc7\xe2\xd1\x1f\xe7\x8e\x71\xf2\x4d\xc2\x09\xcb\x11\xd7\xe3\x28\xc3\xc4\x1e\x45\x0b\x71\x27\x8a\x8f\x73\x43\x70\x67\x2d\xd2\x3d\xec\xc5\xcb\xeb\xcb\xb7\xaf\xae\xde\xbd\x7a\xf3\x9a\x69\xc3\xcb\xff\xe5\x0f\x73\xc2\xe2\x35\xb4\x35\x80\xac\x95\x11\xc1\x6c\x07\x11\x2b\x7f\xd2\xb9\x7c\xfb\x02\x8e\x1e\x21\x3e\x1b\xf1\x18\x1f\x1f\x4b\x80\xd6\xb9\x84\x75\xc5\xb1\xdc\x62\x7b\x14\xef\xd4\xee\x1c\xb8\xf6\x3c\x6c\x3d\x24\x23\x6f\x65\x99\x3f\x18\x1f\xb5\x3d\x62\x62\x7e\x55\x44\x57\x70\x78\x06\xe2\x03\x86\x07\xe5\xb0\x3b\xba\x24\xa3\xc7\xe7\x5b\xc0\xa0\x47\x0e\x00\x95\x2d\xb8\x7e\xf8\x4b\x80\x03\x72\xde\x49\xf1\x23\x60\x7e\xca\x70\xef\x64\xf8\x38\x5c\x25\x47\xe0\xe1\x0b\xe7\x3d\xa6\x3c\xdb\x1a\x3b\x5b\x5e\xd5\x62\x2e\xea\x5a\xe4\xbf\x90\x98\x5a\xd4\x20\x1b\x96\x57\x12\x49\xb9\x99\x99\x1e\xb6\xaf\xe2\x8c\x3b\xd8\x1a\xf0\x2e\xd4\xf0\x7b\x60\xd6\xf8\x58\x42\xee\xa3\xd7\x20\x7d\x11\x6a\x7d\x9a\x5a\x8a\x3b\x91\x4f\xd9\xcb\x04\x6f\x36\x57\x4d\x19\xb5\x6a\xf4\x0d\x52\x71\xf7\xeb\xa0\xd6\x94\x94\xb4\xeb\x44\x48\x37\xf3\xb9\xfc\x60\xc7\x10\x1f\x20\x7c\x71\x9a\xa9\xe5\x98\x7a\xcd\x09\x6f\xbc\xdb\xbe\xd3\x7f\xe3\x8e\x2e\x41\x29\x20\x39\x5c\x14\x6e\xa6\x78\x5a\x9c\xb9\x07\x04\xf4\x4d\xb8\x1b\x71\x49\xf1\x1c\xeb\x8c\xfa\xb7\xdb\x9d\xfb\xda\xb7\xab\xd4\xea\xc8\xc9\x34\xd0\x18\x97\xe5\x42\xe0\x05\x32\x76\x92\x15\x5d\xb8\x71\x4d\x46\x1f\x16\x0d\xa7\xd4\xa6\x8a\x3f\x67\xb3\x95\xbf\xf0\x4f\x07\xdf\x9a\xf8\xfd\x15\x8b\x81\x7a\x61\xe5\xf9\xd2\xdc\xdb\xd2\x5d\xc4\x82\x59\x52\xfd\x67\xaa\x4c\x3d\x17\x26\x5b\x08\x6a\xc7\x0c\x2e\x4b\x91\x4f\x42\xad\x4b\x77\x91\xbd\xd1\x7b\xeb\x2f\x06\x11\xfc\x24\x94\x87\x8e\x72\x6a\x91\xe0\xf8\xab\xd4\x6e\x38\x62\x20\x9d\xe8\xef\xd9\x12\xf3\x1c\x10\x04\x36\xa6\x05\x10\x50\xb7\xd5\xfe\xe6\xea\x9d\xe1\x7b\x2d\xa0\x11\xf7\xd2\x6a\x4b\x1d\x0e\xc2\xa5\x7c\x51\x0c\x05\x62\xed\xc6\xb3\xef\x79\x3d\xe3\x37\x82\x5d\xa2\x88\xab\xda\xaf\x9c\x5c\x54\x85\x5a\x2d\x81\x38\x60\x1c\xf3\x1b\x34\x9e\x29\x3e\x7c\xc6\xb3\x5b\xbb\xa0\xcb\x11\x51\xf0\x6e\x94\xcc\x8d\xd2\x5a\x62\x6f\xaf\xfd\xea\x98\xad\xa2\x91\xc3\x0a\x28\x95\x61\xaa\xae\x16\x7c\x44\x92\x95\xbf\x6e\x0e\x80\x42\x7d\xd8\xaa\x90\x19\xd7\xc2\x4c\xd9\x9b\x12\x4a\xfd\xba\x1f\xe2\x25\x3a\x89\x23\x0d\xf0\x6e\xd9\x43\x8a\xcb\xf3\xbd\xa9\x70\x63\xb9\x0a\xe4\xc1\x74\x17\x57\xa6\xf7\x5b\x4f\x24\x3c\xd3\xbf\x70\x61\x64\x2d\xa0\x71\x7c\x02\xba\xd4\x3d\x5a\x11\x61\x5a\x1f\x39\x91\xe1\x85\x56\xae\x48\x2b\x45\xdb\xcf\x44\xa1\xec\x28\xaa\xf5\x4d\xb7\x4c\xe0\x96\x61\x5c\x37\xc8\xc9\xf7\x9e\x93\xe3\x05\x8a\xe6\x64\xa2\x9c\x9c\x42\xd4\x93\x63\xcb\x16\x54\xc3\x89\x88\x58\x67\x7b\x4a\x55\xff\x3c\x50\x2c\x9e\x01\x0f\x48\xb6\xde\x5e\xc6\x32\x15\x17\xbe\xc1\x0c\xed\x76\x83\x5d\xb7\x18\x2e\xb7\x11\x31\x80\x19\x89\x59\x2a\x62\x6f\x23\x5c\x2f\x03\xae\x78\x6e\xe5\x8d\xee\x92\xc7\x8a\x0f\xe6\xb5\x5e\x52\xd1\xa0\xc7\x23\x29\x98\x0a\xa7\xee\x4b\xc8\x52\x19\x73\x18\x1a\x14\x8e\x5b\x21\x2a\x5c\x69\x19\xe3\x40\x39\x0c\xed\xf0\x89\x28\x54\xb3\x09\xaf\xec\x9d\x92\xa6\x8c\xfb\x84\x33\x4c\xf3\x95\x66\x5a\x1d\x42\x7c\x96\xfc\x83\x5c\x36\x4b\x48\x85\xca\x38\xf6\xff\x84\x45\x3d\x13\xe6\x5e\x08\xf4\x8d\x3d\xbd\x80\x6d\xee\xe9\xc5\x85\x57\x13\x43\x02\x87\xd9\x36\x45\x81\x40\xec\x4c\xba\xc2\x86\xab\x61\x0b\x9d\xf6\x9d\xaa\xc5\x26\x61\xc3\x60\xd4\xd1\x02\xd7\x11\x36\x5f\x62\x7e\xe1\x66\x75\x52\x29\xac\x44\x99\x8b\x32\x5b\xb1\x91\xf6\xcb\xa0\x98\x51\xdc\xc2\xac\x50\xd9\xad\xdf\xdc\x08\x38\x1e\x39\x65\x9d\x15\x9b\x6a\x0d\xf8\xa8\xde\x5a\x20\xfd\x26\x21\x81\x7b\x89\xbc\x7b\x73\x0f\x0d\x71\x04\x1c\xcc\x32\xa1\x99\x6e\xe0\x39\x14\x2b\xcf\x31\x0c\x65\xc1\x41\xa4\x3f\x9b\xd8\xff\x7e\xe6\xfe\x7c\x8a\xee\x6f\x95\x7f\xe6\x7e\x81\x24\x72\xd5\x06\x58\x0b\x5d\x59\x23\xf8\x4e\x14\x2b\x17\xbc\x87\x56\x98\x85\x11\x6f\x60\x50\xdd\x1d\xd4\xe0\x3b\xdc\x7c\x12\x6a\xfa\x6e\x03\x48\x15\x3c\x18\xa4\xf4\xa3\x70\xe6\x63\xf3\xd9\x9f\x35\x61\xae\xfb\x68\x13\x3b\x9b\x60\x36\xc1\x74\x8d\x0e\xaa\x14\x2c\x41\x70\xe3\xe3\x19\x09\x69\x6b\xc9\x8e\xff\xb2\x2f\x9e\x9d\x69\x28\x03\xe4\x42\xee\x62\x38\xc9\xca\xd8\x4f\xcd\xbc\xbd\x7c\x3a\x59\xaf\x6b\x28\xa2\x04\xf4\x4d\xbf\xae\xa1\x31\xb0\xb4\xd1\xf0\x40\xcf\xe0\x53\x2d\xdc\x76\x12\x89\x95\x9d\xe0\x82\x17\x73\x0c\x4e\x50\x5a\x74\x35\xd9\xd3\x75\xaa\x0c\xb5\x74\xaf\x3a\x7b\xba\xab\x2e\x03\x98\x3f\x78\xa4\x62\x6b\xca\xae\x8b\x04\xff\x20\xc2\x91\xc6\x6a\x0c\x32\x9a\xa7\xa1\xf3\x46\x2e\x85\x36\x7c\x59\x6d\xb1\x35\x47\xf2\x14\xb0\xb0\xf3\x85\xbd\x0f\x39\xb4\x0a\xf2\xdb\xcf\x82\x31\xfd\x11\x0f\xb5\x63\xc7\x87\x85\x1e\x7b\x0e\x6d\xac\x3d\x16\x18\x02\x18\x71\x4e\xd8\xc4\x77\xa9\xd9\x1b\x84\xf5\xd1\x9c\x21\x10\xdf\x20\x3d\xde\x8a\x6c\x9f\x1f\x70\x7f\x1d\x7d\x7c\x40\xb5\x82\x94\x75\x27\xea\xf4\x28\x31\xf8\x6d\x38\x46\xb8\xcf\x1f\x81\x75\x78\x44\xb9\x1b\x38\x43\xc8\xb9\x8f\x29\x0f\xb6\xe0\x7f\x92\x29\xd8\x16\xcd\x35\x8a\x2d\x38\x37\xc6\x98\x81\x47\x13\x2b\x5f\xf2\xf3\xdc\x29\xe9\x73\x8a\x4c\x3d\x1f\x77\xa2\x78\xed\x00\x44\xcd\xb3\xfa\xfc\x56\x64\x03\x59\x4a\x47\xf1\xaf\xd4\x69\x85\x47\xa5\x47\x23\x1f\xd0\x78\x7f\xad\x9c\x0f\xc1\x80\xbc\xae\x78\x74\x3f\xf2\xbc\xa6\x60\x05\x80\xe0\x3f\xee\x38\x92\x9e\x6e\xa0\x71\xf8\x72\x3c\x6d\x21\x18\x29\xeb\x74\xae\xdc\x8f\xbe\x11\x50\x96\xcc\xf4\x64\x34\x76\x18\xc4\xa3\x03\x36\x10\xda\x7c\x2c\x3a\x7b\x12\xf9\x9a\xf4\x7b\x91\x15\x8f\x12\x3c\x02\xbb\xc9\xb5\xfd\x3a\x26\x0a\xad\x61\x34\xf6\x93\x27\xe4\x2f\x6d\x3f\x49\x3c\x9d\xa5\xba\xf7\x29\x03\x18\xc0\x71\xcf\x7e\x84\x0e\x20\x6d\x72\xfd\x6d\x57\x72\xb9\xdb\xb0\x7f\x36\xca\xf0\x9e\xe2\xd7\x9b\x89\x97\x40\xe8\x49\xc5\xee\x03\xc9\xd2\xaf\xa6\x63\xf7\x84\x74\x2c\x08\xd5\x48\xdb\x86\xfd\x1b\x1e\xb8\x86\x61\x97\x71\xf9\x64\x17\x0c\x1e\x65\x69\xb2\x5f\xad\xac\xa6\x40\xa5\x8e\xc3\xc5\x29\xd3\x77\xcd\x28\x93\x38\xf6\x37\xce\xe0\xa6\x50\x24\x82\x45\x1d\x7e\x7b\x50\x76\xc8\x76\x71\xc1\x6d\x34\x6a\x56\x25\x4d\x62\x5c\xfb\x5c\x09\x77\x13\x3c\xbc\x9c\x36\x5d\xe6\xf9\xac\x09\x98\xda\x06\x21\xa1\xb0\xc8\x4c\x35\xa5\x41\x5a\x4c\x92\x5a\xd3\xbb\x08\x4c\xd6\xcf\x62\x28\xd1\xc1\x2b\x13\x17\xe8\x2d\xe4\x3c\x34\x34\x9d\xcb\x9b\x9f\x78\xb5\x9b\x00\xb5\x04\xa4\x27\x33\x4e\x1a\x9d\x7e\x72\x0d\xb9\xa0\x61\x85\x2e\xd1\xd3\xa0\x98\xf8\x60\xcf\xff\x22\xc7\xb0\x46\x6c\xca\x6e\x78\xe1\xeb\xf6\xf8\x8b\x1f\x94\x1d\xa4\x9d\x95\x10\x59\xa6\x6c\x63\x51\xea\x7a\x98\xde\x2b\xa3\xbb\xc5\xc0\x5b\xc8\x46\x61\x76\x68\xae\xd9\x21\xe2\xb2\x26\x96\x78\x1e\x66\xab\xdd\x94\xa3\x32\x14\x18\xeb\x99\xb2\x3b\xf7\xa5\x04\x0c\x6e\x7b\x91\x42\x77\x56\x8f\xc3\xd6\xad\x89\x4d\x78\xfa\xb0\xb9\x41\x3c\x49\xac\x29\xd3\x6e\x1b\x4c\x4f\xbb\x20\x2a\x35\xc2\x3d\x7f\xb8\xa5\x50\xa9\xfc\x8f\xb9\x08\x7c\x5f\xbf\x76\x03\x4a\xfa\x9c\x34\xea\x84\xd4\xe9\x84\xbd\xac\x16\x62\x29\x6a\x5e\x5c\x53\x16\xa6\xdb\x52\x5d\x3b\x4c\x37\x17\xbb\xe9\x62\x53\xc9\x11\x2b\x8b\xbc\x7b\x69\xd4\x64\x2c\xc0\x7b\xad\xa3\xa4\x6a\x08\xa5\x57\x0e\x4f\x5c\x7c\xb0\x6b\x09\x9b\x72\x2e\xb9\x84\xeb\x19\x14\xd3\xee\x6c\xd0\xe0\xe2\xb2\x70\xb5\x2f\x53\x20\x2d\xce\xfa\xcd\x28\xca\xce\x8a\x2b\x57\x3a\x7b\xc6\xb9\x36\xcf\x74\xb7\x2f\x28\x7d\xec\xc9\xe9\x06\xe7\xbe\x87\x32\x38\x70\x56\x25\x5f\xca\x0c\x0a\x78\x45\x2d\x3b\xa4\x69\x41\x94\xb5\x80\x33\x75\x92\x11\xdd\x87\x12\xf6\x91\xb4\x43\x24\x9a\xc7\xef\xfa\x59\x5b\xa8\x5d\x58\x2f\x28\x05\x77\x00\xb4\xa7\xc9\x58\x50\x81\xb7\x7a\x50\xd7\xb8\x98\xe9\x47\xa0\x6f\xe8\x88\x7b\xdd\x69\xb3\x7d\x54\xb5\x43\xa3\x32\xf0\xf7\xfc\x11\xd5\xcf\x5b\x4f\xd6\xdd\x37\x61\x5c\xd6\x61\x83\x8b\x80\x1e\x65\x17\x8e\x71\xde\x6d\x1b\xf6\x9c\x1e\xc6\xf4\x63\xd9\x87\x23\x37\x52\xe2\x6f\x39\xf5\x12\x69\xf9\xb1\xfe\xd0\xab\x25\x25\xf6\x2e\x0b\x07\xaf\xff\xda\x96\x61\x3f\xfc\x2d\xd7\xd0\xb0\xce\xee\x59\x43\xed\x99\xf4\x2e\x27\x1f\x50\xbd\xc9\xb2\x1d\x87\xbf\x5b\x59\xc1\x57\xf2\x78\x57\x97\x16\x59\x7d\xda\x1d\x07\x47\xfc\x63\x2e\x9f\x6b\x9a\xdb\xc1\x4e\x7b\x08\xd0\x71\x2e\xfe\x0c\x49\x7d\x8c\x95\xe3\x26\x31\x76\xe7\x19\x58\xea\x29\xea\xdb\xee\x3a\x3d\x3e\xa6\x07\x58\x1b\xe0\xff\x3c\xed\xe2\x80\x21\xff\xa8\xab\x83\x26\x77\xc0\xe5\x01\x10\x4f\xbd\x3e\x68\x1a\x7b\x2f\x90\x04\xf9\x6d\x56\x48\x64\xde\x3d\xb0\x6d\x86\xaf\xc0\x9f\x23\xae\x3f\xb6\x5d\x28\x78\x27\xe2\x0f\x96\x54\xc8\x0d\x7a\xbe\xa8\x65\x65\xec\xe1\x91\x17\x59\x53\xa0\x8b\xfe\x0f\xb3\x66\x8e\xc7\x44\x1c\x59\x67\xaa\x12\x13\xf6\xad\xd0\xe6\xe5\x7c\xae\x6a\x5c\x39\xaf\x95\x89\x7e\x81\x77\x76\xe4\xe8\x9d\xa8\xe5\x7c\xd5\x7a\x06\xae\x90\x99\xa0\xd5\x2b\xa2\x51\x46\x72\xce\xdc\xab\x14\x24\xb5\x22\x02\xc0\x67\x01\xf5\x33\x84\x1a\x37\x17\x0a\x57\xbf\x67\xc9\x2c\xcf\x1c\x02\x9b\x84\xc0\x2c\x84\xac\x1f\x50\x75\x26\xd3\xbb\x52\x70\xa7\x5c\x2a\x03\x69\x9b\x32\x93\x76\x25\x60\x77\xa5\x15\x7a\x95\x7c\x92\x02\x74\xe7\x44\x95\x44\xde\x1d\x00\x3c\xc6\x69\xb6\x83\x73\xcc\x29\xd0\x2e\x37\xf2\x96\x34\xcc\x9a\xa8\xca\xbd\x2c\xfb\xf9\x92\x6f\x38\x27\x7b\x8f\x51\x3e\xa8\x89\xed\xd3\xde\xad\x24\x6e\x6d\x3f\xca\x28\xd9\x38\xa7\x56\xe9\xe0\xf6\x8c\x88\x6b\x3b\x70\xcc\x7e\x8a\x7b\xc8\x11\x39\x36\x82\xfe\x5d\xa6\x3d\x72\x8e\x8d\x94\xa9\x13\xa9\x5b\xdf\x3c\xa4\xbc\x71\xfa\x36\xfe\xe9\x38\x0a\xd7\x84\x11\x80\x70\x30\x8a\x3e\x88\xc6\x8d\x90\x1f\x52\xb9\x67\xe9\x1c\xbd\xba\xa5\xce\x93\x3e\x72\x07\xa4\xde\xfb\x6a\xbb\x57\xac\xad\x62\xeb\x35\xe6\x89\xd9\x17\x87\x5c\xf1\x8f\x58\x97\xfb\x7b\x01\xea\x87\x27\xf2\xf6\x74\x1d\x6e\x6f\x23\xff\x39\x9b\xf3\xa2\x70\xa0\xff\xed\x6f\x97\x9d\xbf\xff\xd8\x0a\xbd\x97\x91\x1b\xf5\x43\xcf\x27\x7d\xc1\x03\xfb\x2a\x88\xc8\xc0\xde\xea\x9c\x39\x6a\x56\x2d\xee\x55\x5d\xee\x71\xb8\x59\x7a\x21\x78\x5e\xc8\x52\x5c\x47\x8d\x5b\xeb\x5e\x46\x52\x3e\x76\x8b\xe9\x1d\xfe\x6e\xcf\xdb\x1e\x3a\x8c\xf0\x47\xf7\x71\xa9\x27\x8e\xa1\x6f\xc7\xde\x4c\xbc\xb5\xbc\x0d\x0b\x6e\x9b\x0d\x60\x33\x6f\xbd\xd4\x8e\x62\xee\x01\xd5\x3f\xfa\x3c\x34\x5c\x1e\x33\x51\xde\xc9\x5a\x95\x10\x8d\x0a\x65\x41\x36\x2b\x77\xfa\x3e\x0a\xc2\xc9\x54\xa9\x9b\x25\xc4\x88\xc0\x6c\x21\xee\x4d\x96\x16\x38\xbb\xe3\x35\x4e\xf5\xb7\xd7\x2a\x17\xb1\x42\x1f\x7b\x14\x72\xbe\xb8\xae\x6e\x8a\xba\x67\x61\x3f\xec\xac\xe0\x35\x34\x7e\x8c\xa6\x85\xa5\x0a\x78\x2d\x01\x3f\xcc\xf1\x8d\x72\x2a\xe0\xa6\x0f\xbd\x40\xee\x8e\x0f\x54\xaa\xa9\xb9\x3d\xac\x43\x6b\x4f\x08\xab\x71\x01\x65\xee\xf5\x60\xa3\xa6\xa9\xa6\x31\x45\xfd\xb0\xd8\xb8\x1d\xd1\xd5\x54\xe7\xc4\x81\xa5\x0d\xe2\x56\x60\x3a\x0a\x25\x0c\x86\x41\x36\x04\x5f\x66\x6a\xb9\x54\xe5\x13\x7c\xbf\x93\x5c\x3a\xcc\x6c\xa8\xfc\xe9\x6e\x99\xf7\x61\xf9\x9d\xe4\xed\x89\x3f\x22\x86\x63\x35\xa8\xb3\x97\xe5\xdd\x77\xb5\x5a\x9e\xed\x24\x00\x04\xb1\x4f\x08\xf6\x11\x80\x18\x6c\x10\x82\x63\x09\x00\x76\x03\x5f\x56\x66\x75\x8e\x53\xda\x8e\xe7\x70\xc1\x1e\x8a\x01\x11\xc5\xf2\x06\xa2\xef\x00\x2c\x9a\x6e\xf8\xbb\x9d\xc7\x86\x10\xc6\x9e\x1e\xb8\xe4\x8d\xc5\x20\xff\x12\xa1\x5a\x50\xad\xd6\x08\xfe\xc2\xbf\xa3\x18\xbf\xd8\x8d\x3a\x5b\x04\x71\xb6\xa8\xe2\x02\x37\x69\xda\x9b\xa2\x36\x69\xb8\x38\x64\xf3\xc7\x28\xad\xdc\x01\xa7\x98\x01\x2c\xea\xe0\xe8\x50\x48\x4d\x3a\xe7\x7b\x79\x27\x30\x14\xcf\x37\x39\x80\xa2\xe0\x82\xfe\x20\xe7\x20\x42\x9b\xb0\xa8\x31\x24\xe6\xd5\xff\xbb\xe1\x85\x8f\xf4\xa4\x7e\xf2\x00\xf8\x5d\xf0\x88\x47\xa1\xb6\xb3\x15\x93\xe6\x0c\x1d\x5b\x32\xa3\xd0\x50\x8f\xab\xb5\x73\x29\xdd\x7f\x2e\xa1\x55\xda\xc4\x57\xa9\x4f\xb3\xe9\xe3\x18\x53\x55\xcb\x1b\x7c\xdb\x2f\xba\xeb\x5e\x79\xef\x8b\x39\x5d\xcf\xd2\xe7\x57\xaf\xd8\x52\x18\x0e\x0d\x9f\x7f\x78\xf7\xee\x8a\x28\x39\x86\xb7\xf5\x9d\xa8\xa9\xba\x9b\x6b\x24\x66\x57\xe6\x3b\x5c\xc2\x35\x2f\x35\x70\x17\xeb\x74\x85\x5e\x71\xbe\xfe\xc6\xe7\x17\x5f\x62\xf1\x72\x48\x9f\x16\x65\x4e\xea\x26\x57\x42\x63\x83\xcd\x65\x55\x80\x85\x15\x50\x5c\x2f\x33\xaf\xb4\x6e\xec\xd2\xa0\x89\xe0\x89\x84\x34\xc4\xf3\xab\x57\xd3\xf4\x41\x22\x38\xf8\x48\x07\x63\x03\x1a\x93\xa9\xb9\xc5\x72\x6b\x93\x02\xb2\x1f\xa2\xd6\x3f\x6d\xaa\x43\x7f\x99\xf3\xd0\x80\xfb\x1c\x3b\xd9\x9d\xf3\x32\x3f\xaf\x85\x36\xbc\x36\x63\x7a\xf5\x41\x83\x1e\xcb\x83\x6e\x84\x2f\x41\xc1\x91\x20\x45\x2f\x04\xd3\x0b\x56\x70\x1d\xd5\xbd\x70\x95\x89\xa8\xa5\x8e\x4f\x9f\xa9\x6a\x71\x27\x55\xa3\xa9\x11\xcf\x36\xc5\x59\xf0\x0b\x2a\x81\x51\x0b\x55\x89\xd2\x19\x77\x83\xe3\xa3\x89\xb7\x16\x87\x89\x8b\x13\x82\x46\x70\x76\x83\x90\x65\x03\x19\x6d\xd2\x9e\x97\xcb\x1b\x2b\x36\x72\x4e\xd7\xb9\xba\x15\xd9\x5e\x29\x59\x62\xdb\x79\xd9\x53\xfd\x77\x53\x74\x7b\x6f\x4f\xa0\x0e\x23\xed\x68\xbe\xef\xc8\xf9\xe8\x3a\xe5\x6b\x38\xd9\xc3\x47\xaa\xe5\xe1\x9b\xaf\x77\x38\xb9\x33\xab\x62\x46\x71\x56\xf1\xda\xc8\xac\x29\x78\xdd\xcf\x2c\xe9\xf4\x2a\x9d\xfb\xa1\x51\x45\xc2\x01\xb6\xe0\x55\x25\x20\x1a\x0e\x73\xe1\xa9\xb5\x62\x0b\x5f\xc8\x14\x9c\x0d\x54\xf7\x3e\x0c\x63\xac\x9a\x3a\x77\x09\x88\xe7\xf7\x44\xef\xed\x39\xe3\xfa\x4e\xf1\xdc\xf7\xa7\x99\xc4\x5d\xa7\x42\x9b\xaa\x94\x10\x18\x69\x42\xd8\x6c\xc1\x20\x9f\x33\xe9\x50\xc6\x92\xfc\x7e\x99\x67\x42\xde\x61\x9e\x54\x8c\x91\x0f\x7f\x20\xac\xd6\xe1\x82\xc3\xd0\xd6\xdc\x2a\xf2\x03\x20\xa0\x42\x3b\xa9\x6e\x1c\x2e\x05\x07\x55\xac\x02\x3c\xa7\xc4\x41\x85\x93\xdb\xc5\x0e\xb1\xa1\x84\xcf\x61\xd8\x0c\x83\x9c\x53\x21\xfe\x3d\xb8\xeb\xfb\xb6\x7a\xa7\x85\x9c\x33\x89\x54\xd0\x46\x55\x9a\x2d\x45\xc8\x20\x8b\xa3\x22\x9d\x41\xe1\x69\xb8\xf5\x62\x0c\x55\x8e\x37\x8f\x44\x9f\x9c\x69\xb2\x27\x5d\xea\xa1\xef\x98\x86\xaa\xd2\xcf\x8b\x04\x62\x42\xc5\x57\x0b\xec\x32\xec\x1e\xf7\x68\x4f\x45\x6b\x96\x30\xc2\x76\x22\xd2\x00\x52\x3a\x99\x28\x04\x9e\x46\xd8\xc1\xc5\xe8\x81\xd9\xac\xad\xed\x84\xa5\x08\xb6\xe4\xac\x13\x5d\x2a\x43\x85\x4b\xc0\xb5\x0f\x45\xb2\xfb\x1a\x9f\x50\x3e\x4e\xd5\xb9\xd8\x86\x79\x5d\x70\x98\xb4\xe8\x90\x26\x4b\x1d\x6a\xaa\x61\x34\xb1\x35\x15\x4b\x69\x64\x70\xe5\xf2\xd2\xae\x62\x6a\xa3\x4b\xfc\x83\x4a\x69\x88\x34\xcd\x21\xda\x48\xb1\x2e\x0b\xed\x8d\x04\x0c\x7b\x5d\xba\x80\x8b\xee\x2e\x3f\x0f\xa5\xa3\x50\x0c\xa0\x04\x14\x0a\x18\x25\xaa\xb5\x3f\x42\x51\x2b\xa8\xae\x28\x22\x03\x2b\x7b\xea\x2a\x61\xd9\xa9\x56\xb5\xca\x9b\xcc\xa1\x77\x5f\x4b\x03\xbd\xdb\xc9\xbe\xc3\xac\x75\x76\xa3\x6a\xd5\x18\x59\x76\x37\xe0\x9e\xe3\xc8\x66\xc9\xb8\xa4\x1a\x76\x18\x67\x21\xea\xf1\xad\x41\xd2\xf7\xfd\xc1\x4d\x92\xff\xba\xf5\x78\x8b\x45\x5c\x82\x51\xdd\xfa\xde\x9b\x42\xbe\x48\xdd\xb7\xca\x40\x3d\x0c\xb6\xe4\xff\x22\xf7\xa1\x65\xc6\x52\x96\xaa\x0e\x74\xc7\x5e\x87\x76\x5f\x9d\x81\x56\x92\xa5\x11\x37\x3d\xad\x6d\x37\xe5\x99\x22\x3a\xef\x07\xec\xd1\x17\x5c\x2c\x55\x79\x2d\xcc\xf9\x77\x5c\x16\x22\xbf\x52\xb9\x73\xb9\xf7\x12\xb2\xd2\xbf\xd3\x37\xe0\xb5\x6f\x27\xe8\xd9\x59\xae\x7c\x2b\x42\x38\x7c\x8a\x9c\xe5\xf8\x41\xe5\xca\x21\x6c\x3a\xfe\x65\xee\xb1\x61\xff\xdd\xcc\x44\x5d\x0a\x2b\x4f\xb9\xd4\xa6\x96\xb3\x26\x9c\x6d\xe9\x40\x6c\x8f\x67\x7e\x1e\xa1\xe8\x02\xa4\x56\x42\x4b\x9c\xde\x33\xf0\x45\x1f\xdd\x2a\xfd\x04\x91\x7d\xaf\x85\x19\xa6\xd5\x5b\x55\x14\x56\xb2\x77\x22\x11\x7d\xeb\x6b\x1a\x37\x65\x29\x32\xa1\x35\xc7\xbb\x11\x6b\xf4\x1d\x96\x4c\xee\x88\xc6\x1b\xa3\x96\x98\x47\xbd\x94\xa5\x5c\xda\x63\x25\x66\xfe\x4b\x5d\x37\x15\x66\x54\x38\xec\xd4\x3c\x74\x23\x51\x8c\x87\xc9\x1f\x94\x90\xaf\x55\x2e\xae\xc5\xba\xa2\x87\x9b\xa8\xd9\x60\x0b\x48\x68\x12\x94\x29\x7b\x6c\xfc\xe0\xe4\xed\xd0\xf4\x4b\x64\x8c\x95\x2a\x17\xd1\xd6\xeb\xba\x93\xa4\xb6\x4e\xb7\xf6\xdd\x3e\xd4\xda\x6b\x65\xc6\x84\xd2\xd8\x05\xf0\x48\x74\x32\xb1\x13\x4a\xcd\xc3\x04\xc8\x7d\xf2\x2b\xe6\x3c\xa7\xe4\x8c\x33\x2b\x2d\x80\xf0\x34\x6b\xd7\x66\x8a\x6b\x12\xf0\x4c\x78\x5f\xe6\x95\xea\x1e\x21\xf6\x5d\xe5\xb2\xbc\xf9\xd9\x25\xc4\x6c\x4d\x73\xca\x43\x85\x5b\x26\x3b\x67\x6c\xe4\xc3\x7d\x4e\xab\x57\xfd\xf4\xa2\x36\x35\x37\xe2\x06\x4a\x7f\x24\x83\x1f\x51\x94\x93\x71\x0e\x22\xae\xa1\x6c\xc7\x5b\xb1\xa6\x3b\x2e\xd0\xae\xfb\x6e\xf4\x53\x5a\x1c\x4f\x15\x39\x15\x0a\x28\xf3\xd0\x75\x17\xeb\x5a\xaa\x52\x6c\xae\x72\xba\x8b\x18\xbf\x48\x4b\xaa\xd0\x7d\xa7\xf3\xed\x12\xbb\x3a\x44\x7b\x36\x44\x34\x0f\x6d\x1d\xd1\xc6\x49\xdd\xc0\x07\x1b\xc9\xe7\x65\x2e\xda\x3c\x4f\x4b\xbe\x44\xb0\x8f\x44\x43\x71\x27\xad\xb5\xf3\x83\xd4\x46\xd5\xab\x1f\xe5\x52\xf6\x87\xc5\xb7\x48\x99\xaf\xa3\x5e\x94\x5d\x75\x38\x6a\x65\x85\xe0\x25\x6b\xaa\x08\x8b\x33\x1d\x25\xfa\x50\x8d\x2b\x1e\xda\xb3\xa4\x6f\xfe\xdf\xa9\x55\x2a\xd3\xba\x67\xc2\xff\xf7\xb0\x34\xbd\xaa\x95\xe5\x2b\x1e\x50\xae\x33\x5e\x0c\xdd\x03\x6c\xa4\xa9\x93\x90\x2a\x86\xa8\x3d\xc4\xc3\x1b\x3e\x11\x36\xf1\x98\x14\x43\x03\xe3\x4e\x98\x9c\x8a\x69\xf2\xb8\x58\xc1\x43\xbb\xd3\x0c\x31\xc7\x95\xef\x78\x91\x96\x77\x92\x1a\xbf\xec\x6e\x47\x7b\x6b\x06\x75\x37\x90\x2f\x35\x9a\xea\x35\x41\x39\x26\x95\xdd\x18\xe8\x8d\x02\xca\x42\x90\x0d\xe3\xf5\x4c\x9a\xda\x5a\xba\x65\xb3\x9c\x89\xda\x9a\x07\xe8\xb2\x01\x33\x33\x17\x1a\x5a\xc1\x68\x63\x75\x43\xde\x80\x63\xb7\x46\x85\x11\x27\xa6\x46\x25\x17\x61\xa8\xc6\xd8\xe3\x9b\xd4\x8b\x9e\x1d\x6c\x7b\x92\xff\x97\x9a\xe9\x49\x5c\x4f\x69\xc2\x6a\x71\xce\x73\xac\x9c\x34\x48\xfd\xff\x52\x33\x47\x6b\x78\x17\xcf\xc9\x70\xd1\x04\xa0\x5c\x14\x09\xa6\xb8\x96\xaa\x3c\x5f\x86\xeb\x34\x86\x7b\xdb\xc8\x9b\xdf\x8a\xd7\xbc\x28\x44\xc1\xfe\xa5\x66\x78\xe9\x17\xc8\x09\x45\x93\x5a\x17\x58\xd4\xb2\x64\xee\x3f\x94\x7a\x89\xb6\x18\x55\x18\xe3\x2e\xa2\x11\x4b\x6c\x58\xa4\xa5\xe9\x54\x56\xc4\xa1\xec\x3c\xe9\x02\x05\x89\x42\x37\x55\x54\xbf\x8a\x61\xf6\xfb\x4f\x58\xab\xc3\xb8\xe6\xc5\xe0\x48\x88\xfa\x45\xfe\x97\x9a\x9d\x69\x2a\x41\xdb\x82\x1a\x72\x80\xfb\x2c\xba\xde\x1b\x98\x4a\x3f\xb1\xa4\xe8\x65\x24\x46\xf4\x10\x23\x6f\x6a\x9e\x89\x79\x53\x84\x58\xba\x71\x1c\xf5\x05\xd6\xff\xa5\x66\x63\xb9\x04\xcc\xf1\x0e\x02\x11\x23\xe2\x9b\x12\x02\x43\x44\x61\x19\xd2\xa9\x1b\xd2\x76\xe5\xda\x87\x00\xd3\xd3\x2a\xaa\xe9\x17\x67\x61\x8f\x73\xb0\xac\xa3\x19\x9e\xa4\x60\x8d\x93\xf7\x9e\xeb\x5b\x38\x47\x63\x08\xff\x46\x7a\xc1\x71\x03\x88\x65\x54\x0c\x0d\x0f\xe5\x5c\xdf\x6a\xa6\xd5\x52\x40\xc5\x41\x80\xeb\x27\x0b\x17\xa5\x0a\x73\xd1\xfd\x8d\xd8\x26\x2f\x4c\x88\xc3\x0d\x95\xe5\x70\x14\xa3\xf0\x4a\x5e\x95\x99\x20\x3f\x99\xa5\x10\x7b\x0e\xd3\xa2\x01\xec\x06\xe0\xaf\xc8\x3c\x75\xc5\x07\x91\x35\xd8\x43\x32\xcc\x60\x1f\x79\xa4\x9d\x83\x5d\x0b\x33\x69\xeb\x08\x6f\xda\x46\x0a\x22\x7d\x3a\x48\xf6\x28\x2d\xb8\x5f\xff\x00\x6c\x55\x86\x43\x59\x34\x0e\x5d\x58\xb8\x3e\xab\xe9\x37\x9b\xb6\x88\x76\x59\x68\xac\x36\x15\xcf\x93\xfd\xf5\xed\xf5\xa7\xec\x1e\x0a\x67\xb6\xdb\x08\x48\x72\x2b\xba\x9b\x02\x0a\x2a\xb3\xda\xe0\xed\x35\xb1\x40\x82\xbf\x34\xa8\x19\x3b\x22\x94\x1c\xc5\xe5\x48\x45\x3d\xa1\x8a\x53\x64\x63\x72\x30\x6b\x01\xda\xaf\xe4\x05\xf2\x5a\xa8\x8c\xb5\x10\x28\x4b\xac\xd2\x4c\xd7\x8e\x6f\xaf\x5d\xd3\x26\xe8\x4f\x4b\x74\x69\xe1\xf9\xf6\xfa\xac\xdd\x98\x60\xe2\xbe\xee\x53\x62\xf1\x21\x8f\x7e\x22\xbf\x7d\xbb\x76\x6d\x5b\xba\x3e\x1b\x90\x2e\x32\x46\xfb\x0e\x60\x89\x94\xd9\x75\x38\xe3\x5a\x66\x4c\x2e\x31\xa8\x70\xac\x0c\xb9\x6b\x83\xe8\x6b\x4b\x3c\xf0\x62\x3b\x53\x38\x22\x38\x34\x1f\x71\xef\x8d\xcf\xde\xf1\xa3\x52\xc5\x4a\x47\x2c\xce\xb4\x2c\x6f\x0a\x11\x42\x99\xa6\xec\x27\x7e\x2b\x98\x77\xb7\xfa\xf5\x4a\x42\x58\x37\xd0\x58\x07\x23\x8d\xae\x7f\x78\xf3\xf3\x8f\x2f\x98\x16\x00\x0a\x4b\xd9\xd6\x42\x57\xaa\xd4\x02\x75\xd0\xbf\x1b\x51\xcb\x91\x55\xfb\x46\xd1\xbb\x55\x44\xb0\x77\x81\x6f\x22\x7f\x2b\x15\x79\xdc\x6a\x1e\x63\x32\x97\x28\x68\xd0\xde\x64\xfd\xa2\x6d\x4d\x83\xfd\xf5\xed\xe5\xa7\x4c\xea\x90\xb2\x00\x45\xeb\x06\x96\x73\xef\x52\xbe\xec\x5f\xca\x3e\x2c\x70\xed\x72\x0e\x4b\x79\xf4\xca\xc8\xc6\x32\xc8\x2d\xd2\xdd\x39\x13\x74\x75\xaf\xfe\x1c\x75\x98\x59\x4f\xf7\xc0\x26\x97\xbe\xd6\x2e\x8a\x19\xf9\xd4\xd6\xab\xb9\x1e\xb5\x16\xab\xb4\xcb\xae\x4a\x0b\x99\x89\x97\xe3\xd5\x5a\x47\xa5\x75\x76\xcc\x03\x70\x6e\x3b\xad\xd6\xcf\xbc\x11\x0a\x2e\xa4\x9a\x6d\xa7\xe0\xd6\xf6\x32\xe8\x44\x6b\x7e\x0b\x08\xbc\x5a\x52\x79\xa4\xa8\x5f\x51\x53\xfa\x1b\x29\x99\x51\xaa\x06\xc6\xc6\xa8\x3b\x99\x8b\x1c\xb1\x99\xd2\xb7\xce\x24\x34\x42\xbb\xb2\xc3\x12\x0e\xb7\x4c\x96\xd4\x7d\x21\x86\x06\xd1\x68\x25\xde\xfe\xd5\xaa\xb9\x59\xb0\x77\x97\x57\x13\xf6\xf3\x8b\x2b\xc0\xe2\x87\x77\xef\xae\x46\x6b\xc7\xd1\x9c\xc3\xa6\x33\x73\x55\x33\xa9\x75\x23\x34\x2b\xe4\xad\x88\x6a\x28\x85\xaa\x3f\x2e\x2d\x62\x17\xce\x36\xf5\x1c\xca\x37\x3a\x8b\xd5\x9e\x65\xf1\x72\xd5\x75\xed\xe4\x0c\xa3\xe3\x10\x8d\x18\x0b\x37\xf4\x0e\x71\x99\x03\x6c\x07\xb6\x81\xd6\x0e\xf3\xf4\x7d\x76\x7d\xad\x49\xaa\x19\xd5\x1f\xc1\x39\xd6\xa0\xef\x32\xe2\xda\x1e\xa5\xe7\x4d\x01\xd6\xc0\xb7\x4d\xad\xcd\x46\xe7\x4d\xf4\x09\xfb\xed\xf6\x6f\x7a\x2a\xd5\xef\x24\xa4\xf1\xa3\x79\x53\x66\xe8\x29\x91\x66\xc5\x7e\x8b\x1e\xc1\xbb\xd8\xaa\x0d\x47\x24\x27\x4b\x7c\x38\x48\x8f\x05\xe2\x4e\x94\xae\x5b\xec\x42\xf0\xc2\x2c\x56\x64\x81\x5e\x17\xea\x7e\x53\x44\x74\x8c\x55\xc7\x07\x79\xe5\xce\xca\x57\x2a\xff\x89\x97\xfc\x06\x2e\x0c\xa8\x38\xb0\x15\xc4\x99\x45\x31\xf6\x05\x59\x26\x48\x0d\x34\x0c\x11\x89\x58\xe4\x1e\x2f\xb5\xab\x5a\x40\xd3\x25\xe8\xe3\x27\xe6\xbc\x29\x0c\xa3\xfa\x66\x97\x05\xd7\xda\x6e\x69\xa8\x3b\xa8\xb0\x16\x2e\x58\x2d\x55\xd9\xbd\xc0\x1d\x5a\x53\x9a\x26\xd5\x63\x71\x24\x3c\x3d\x25\x37\xaf\x53\x3e\x62\x88\x97\x3d\xb7\x56\xb5\xc8\x65\x86\xa5\x9f\x31\x7c\xc2\xaa\x90\x05\x2f\xb0\x36\x6d\xb9\x62\x6e\x3a\x70\x1b\x22\x75\xe0\x33\x6e\x92\x3b\xb1\x99\x16\xde\x15\xa5\x51\x70\x9d\x89\x32\x47\x87\x4b\x8e\x51\x16\xaa\xce\x65\xc9\x0b\x26\xcb\x5c\x7c\x00\xc3\x2f\x66\x34\x6b\xaa\x24\x82\xcb\x01\xb2\xa3\x26\x90\xf0\xf6\x86\x3e\xca\xd5\x7d\x39\xf5\xa4\x80\xee\x78\x0c\x8c\x18\x75\xef\x1b\x23\xdb\x33\x28\x4d\x9c\x2a\x61\xdb\x0d\x57\x86\x3e\x47\xf1\x5c\xec\x66\xee\xc9\x81\xc2\x87\xca\x7a\x3f\x01\x3c\x85\xf0\xf9\xbb\x10\x8c\x1e\x20\x3b\xed\x04\x82\xe8\x43\x7b\x70\x78\x71\x27\x21\xb3\x2f\xc2\x7b\x5b\x61\x4a\x6c\xd0\x44\xb2\x8c\x35\x69\x28\x5a\xee\x46\xc1\x66\xca\x38\xcd\x98\xc2\xc2\x20\x16\x10\xfa\x98\x70\x1d\x05\x1e\x60\xad\xe5\x7f\x61\xd6\x21\x44\xf3\x20\x9a\xb3\x15\xe3\xec\xb5\xca\x45\x9f\xaa\x41\xc5\xf1\xf8\xb8\x1d\x62\x83\xdc\x09\x53\x9f\x50\xf5\x78\x95\x03\x36\xdb\xbd\xaa\x6f\x31\xcf\x96\x17\xf6\x4c\x38\xf3\xb8\x8d\x3c\x79\xf6\xcd\x6b\xca\x5e\x8b\xfb\x38\xd2\xbe\x6f\xee\xde\x38\x23\x4c\x10\x03\xf4\x6d\x4e\xd9\xb7\xb5\x0b\xd7\xf3\xbf\xb7\x57\x7b\xc8\x86\xab\x40\x19\xdc\xab\x69\xfc\xdc\xeb\xa7\x60\xcf\x71\x03\xc9\xbb\xbe\x6c\xfe\x58\x0f\xd4\xe8\x45\x4c\x0e\x76\xba\x92\x83\x6d\xf8\x8a\xd7\x46\xae\x75\x8e\x1e\x81\xb9\x95\xa8\x2d\xeb\x58\xc6\x4b\x5e\xaf\x7c\xfc\x09\x34\xfd\x59\xc0\x15\x58\x7a\x17\x80\x11\x97\x62\x59\x15\xd0\xb4\x50\xe5\xad\x10\xc6\xd1\x1a\xe0\xac\x7d\xdf\xee\x6f\xe2\xfb\xcc\x09\x24\x0c\xb8\x6e\x97\xc2\x90\x73\x08\x42\x61\x2d\xde\xb2\x8b\xb1\x6a\x8c\x9e\xb2\x57\x73\x32\xfa\xa3\x9c\x91\xfb\x85\x84\x0b\xa6\x74\x5e\xee\xbc\x0d\x1b\xab\xba\xa9\x85\xd6\x93\xae\xc2\xaa\x85\x36\xee\x16\xc4\x9d\x25\xa0\x47\xba\x54\x05\xf7\x61\xa3\x1e\x5f\x97\xba\xb2\xbf\x65\x73\x92\x8d\x25\x91\xc9\x87\x10\xc2\xb6\xa8\xc1\xc6\xa0\x8a\x02\x42\x1a\xd7\x48\xde\x3e\xb6\xea\x80\x10\xda\xfd\x06\x63\xb7\xb0\x46\x2b\x85\x77\xa2\xa3\x04\x5d\x98\x25\xa8\x09\x0e\x09\x0e\x7e\x03\x02\xb1\xf0\x58\xd2\x3d\x1b\x1e\x31\x52\xe1\xd7\xad\x94\x79\x59\xe6\x76\x3a\x54\x46\x1a\x63\x5b\xdd\x9d\x3a\x10\x02\x31\x74\x3f\x81\x6c\x83\xcb\xdd\x8d\x25\x9d\xbb\x21\x77\xb9\x9a\x2e\xcc\xbc\xaa\xa5\xaa\x99\xbb\xaf\xee\x11\xeb\x5c\x18\x91\x59\x72\x48\x8d\x85\x6a\x7d\x48\x9a\x2c\xb5\x11\x3c\x77\x09\xc1\x3e\xca\x10\x5d\x44\xb5\x47\x66\x7b\x19\x47\x9b\xe2\x44\x72\x7e\x29\x6a\x8a\xb5\x16\xd7\xf2\xc6\x1e\xc0\x5d\x05\x05\x6c\x1d\xdd\x91\xf4\xc6\x2c\x7e\x8f\xbf\xd2\x6c\x6d\x8b\xec\xd6\x85\x2f\xa6\xa7\x5f\xbf\x85\x8f\x54\x25\xea\x51\x62\x7a\x86\x07\xd1\x68\xd0\x29\x2e\x2f\x00\x83\xdd\x91\x43\xf7\x59\xdf\xfd\xfc\x09\xf4\x64\xf6\x0d\x8f\xd1\x94\x51\x59\x03\xd7\xac\x43\x20\x9f\xdc\x3d\x0d\x50\x9f\xb8\xb8\xd9\x00\x3d\x01\xfe\xa4\x07\x80\x0b\x62\xa4\x16\xd4\xc3\x03\x22\xb9\x5d\x2d\x96\xc9\x9a\x67\x96\x8b\xb5\xba\xe3\x45\x48\xa8\x58\xf3\x32\xd5\xb2\xf2\x95\x2d\xb6\x41\xfe\xc9\xdd\xd3\x1d\xf1\x0f\xa6\xc4\xb2\xb1\x87\x6c\x52\x24\x68\xbe\x20\xde\x37\x56\x97\x16\x52\x9b\x89\x0b\x15\x77\x89\x2b\x15\xfe\x19\x27\x05\xe0\xbf\xa3\xc6\x76\x1b\xc6\xf7\x34\x4a\xc3\xcd\x13\x64\x00\x81\x64\xcc\x8d\x50\x23\x65\x34\x1a\xe6\xd9\x98\xa8\xe8\xc6\x2c\x52\x06\x74\x92\x5c\xd1\x31\xc6\x33\x2c\x51\x60\xd4\xad\x28\x35\xa8\x5e\xb6\x84\x5f\x30\x02\x80\x54\x70\xff\x3a\x25\x20\xcf\x33\x2a\x80\xe2\x7c\xf8\x10\xfe\x60\xbf\xb7\x87\xca\x06\xfa\x62\x5b\x99\x87\x31\x50\xbb\xc3\x08\x5b\x84\x9b\x3b\x74\x69\x28\x76\x2b\x56\xe8\x18\x06\x48\x50\x25\xc2\xa8\x70\x69\x56\x16\xab\x70\x00\x7e\xde\x18\xf5\x93\x7d\x8d\x80\xbc\x03\x34\x24\x2a\x4b\xea\x98\x34\xe7\x85\x16\x53\xf6\x2b\x3a\x14\x31\xe9\xc0\x1a\x33\xf7\x68\x78\x0b\x6b\xeb\x28\xcd\x16\xa2\xa6\xa2\x28\x4f\x7d\x2a\xfa\x95\xca\x27\x78\x0f\x53\x89\x0c\x7a\xd2\x3d\x77\x33\x4c\xe9\x83\xe3\xd2\x80\xa5\x2c\x18\xff\xd4\xcd\x0b\xf1\xcc\x42\x15\x16\x6f\x90\x40\x2a\xee\x84\xcd\x3e\xed\x90\xc0\x6e\x19\x2e\xc3\x09\x0a\x65\xac\x1b\x96\x82\x77\x31\x4d\xb4\xb6\x10\xb3\x03\x42\x04\xea\xb1\x67\x7b\x92\xc4\xe2\x85\x0a\xa8\x8b\xda\x78\x9a\x44\xe8\xc3\x47\x87\xa0\xca\xae\x30\x91\x2e\x9f\xed\x49\x17\x80\xf2\x47\x24\xcc\xbb\x45\x74\xe5\xe9\x2f\x35\x69\x13\x71\xbd\xc8\x60\x77\xa1\x32\x51\xa0\x0a\xa2\x0a\x94\x00\xf7\x17\x55\x34\x4b\x6a\x79\xca\xcd\x02\xa4\xd8\x6b\x31\x11\x29\x83\x2d\x28\x4f\x9a\xc1\xd9\x73\x88\xae\xdd\x36\xd2\x97\x5d\xba\xd8\x58\x78\xae\x2f\x34\xc0\x9b\xa0\xd9\xe7\x33\xe0\xa1\xb1\x04\xd7\x42\xb3\xa7\x7c\xf2\x74\x36\x79\xc6\x27\xcf\x66\x30\xe8\xb3\x6c\xca\x5e\x95\x64\x74\x86\xb7\xb2\xc9\x67\x7c\xf2\xd9\xcc\xef\xd9\x9f\x65\x03\xb4\x49\x5b\xf7\x44\xb4\x19\x63\xe0\xd9\x8d\x84\x6e\x51\xde\xd3\x66\x31\xb8\x99\x38\xb2\xbc\xc3\xcd\xe4\x27\xbb\x91\x79\xed\xbb\xed\x2e\x82\x7b\x04\xe5\x19\xe1\xd6\x01\x4a\x1e\xa4\xe2\x28\x5b\x47\x74\xfd\xee\x0b\xd7\xb9\xea\x1c\xd8\xe4\x37\x0b\xd2\x0a\x57\x67\x70\x0f\x5c\x0b\x9e\x77\x46\x01\x84\x27\xac\x56\xca\xb0\xcb\xe7\x64\x72\x04\xfb\x3b\x5c\x85\xc4\xfd\x7b\x43\xc6\x9b\x5b\xd1\x76\xee\x28\x42\x40\x43\x90\xf0\x29\x7b\x5e\x14\xb4\x44\x00\x2d\x94\x29\x59\xa4\xb6\x98\x2b\x51\xd6\xc6\x6c\xe9\x01\x05\xa7\x4b\xbc\x5e\x90\x18\x68\x49\x7b\x82\x1c\x56\x50\x1c\x2a\x85\x9c\x0b\x6c\x3e\x6c\xb0\xbc\xe6\x56\x02\x82\x37\x86\x78\x9b\xe7\x8a\x11\x23\x34\xc8\x18\x4d\xbf\x1a\xe1\x23\x41\x25\xad\x3b\x9f\xba\x4b\xd1\xb8\xd6\x45\x20\x5d\x9e\x8b\xdc\x9e\xdd\xf4\x42\xdd\xfb\x7c\x71\xcc\x69\x84\x14\xc2\x29\xbb\x72\xd7\xe4\x11\x37\x1c\xe8\xb8\x38\x03\x14\xd4\xb0\xa7\x3b\xac\x04\x63\x56\xbe\x10\x88\xbf\xce\x6c\x53\x22\xfe\xdc\xab\x87\x3e\xec\x01\x36\x35\x7e\x4b\xca\x7b\x74\x5e\xb6\x87\xfe\x10\x69\xe7\xae\x68\x31\x63\x90\x07\x5f\x4e\x34\xc1\xb1\xe6\xe8\x26\xe1\xf8\xef\x66\x26\x32\x53\x4c\xd8\x8d\xb5\x8d\x67\x4a\xdd\x32\x5e\xc5\xad\xcb\xdb\xd2\x91\x15\xf2\x77\xf7\x15\xcb\x0a\x29\x4a\xc3\xbe\xef\xfb\xb6\x5d\xb0\x97\x52\x83\xe8\x72\xd4\xf9\x57\xe3\x0f\xc6\xb9\x56\xfb\x07\x4b\xcb\xfa\xf0\x92\xf1\x9b\x72\xa1\xb4\x61\x55\x2d\x97\xbc\x5e\x51\xd2\x24\x1e\x5a\x9e\xf9\xa7\xce\xe5\x39\xb1\x5a\xa0\x34\x10\xcd\x13\xa0\x46\xbf\xba\x3b\x6d\x08\x1d\x4a\x41\xd3\x1e\xdb\x7d\x1e\xe2\xf9\xa9\x04\xf4\xcf\x9a\xca\x2c\x24\x30\x27\x41\x8a\x40\x12\x20\xbb\xd5\xe5\xec\x8a\xd2\xd4\xab\xa0\x2d\x7b\xb9\x44\x69\xf1\xf0\x71\xf0\xd8\xb5\xbe\xa4\x3a\x28\x08\x97\x10\x84\x97\xa7\xec\x79\x04\x6a\x6e\x4f\x11\x20\x7c\x96\x43\x76\x8d\xf9\xa2\x86\x4e\xb7\x41\xb1\x14\x8b\xa4\x11\x69\xd3\x9d\xd0\xa0\x0e\xca\x07\xf0\x31\x5b\xdd\x2d\x4a\x92\xfb\xdf\x41\xf1\xc4\x6b\x7d\x77\x74\x87\x13\xed\x18\xc9\x74\x7f\xf2\x4a\x9e\xfb\xc4\x57\x27\x98\x00\x52\xce\xd9\x1d\xf4\xd7\x96\x74\x6f\xef\x27\xc1\x2b\x19\x92\x65\x37\xc5\x63\x34\x25\xa3\x29\xd8\xc9\xdf\x08\x93\x7c\x3e\xb1\x27\xb2\xca\x95\xc4\x23\x31\x25\x1d\x22\x72\xff\x5a\x88\x06\x39\xbb\x7b\x7a\x46\xd5\x7c\x0e\x49\x44\xf4\xe2\x30\x59\xce\xd5\x96\x04\xa4\x4f\xcf\xed\xa7\x1d\x02\x86\xe8\x7d\x0a\x63\x84\x51\x7c\x43\xd0\x60\x70\x41\x61\xc1\x04\xd4\xa6\x35\xcf\x8b\xa2\x4d\xd8\xf8\xfb\x7e\xc2\xc6\x6f\x44\x75\x81\x48\x86\xa3\x5c\x83\x9f\x10\x53\x0a\xe6\x9b\x09\x1f\xe3\x77\x38\x9a\xe3\x74\x66\x98\xa4\xa7\x6a\x6c\x97\xbc\x0d\xe5\x3d\x80\x36\xd5\x6f\x5b\x2f\xa0\x35\x5e\x4b\x4c\xe7\x2f\xc4\x1d\x87\x92\x34\xa1\x50\xd2\x1c\x86\xc7\xbb\x83\x11\xf6\x1c\xa6\x5b\xc4\xba\x34\x4a\x94\xc4\xda\xad\x41\x93\x38\x15\xd7\xc6\x3a\x64\x1e\x10\x91\xa3\x8d\xd3\x52\x60\x12\xac\xb2\x09\x85\x96\x4d\x28\x3b\x03\xca\xbe\x40\x48\x5f\x3c\x09\x8e\x32\xe6\xb4\x52\x77\x44\xa6\x4a\x56\x67\x93\xa0\x5d\x4b\x95\x23\xb0\x60\xff\x11\x2e\xd0\xe1\xdb\x17\xa5\x62\xae\x1c\x60\x34\xdc\x21\x05\x41\xce\xe7\x69\x1e\xcf\x56\x52\x60\xbf\x1e\x94\x00\xfb\xd0\x1a\x0b\x94\x7c\x07\x3f\x60\x70\x1c\x30\xfd\x45\xd4\xac\x7c\xe4\xf5\x65\x2b\xb1\x8e\x2d\x8c\xa9\x7c\x34\xd8\x0b\x2c\xf7\x87\xd7\x90\x7c\xd9\x9f\x86\x17\xb0\x30\xf8\xdd\x84\xcd\x1a\xbd\x9a\xa9\x0f\x53\xf6\xc2\x22\xac\xe6\xac\x90\x77\x9d\x8f\x5d\x31\xc1\x3c\x7e\xe0\xb7\x99\xb8\x76\x59\x34\x4b\x6a\x04\x8e\x00\xd1\xee\x27\x20\x88\xf2\x08\x73\x69\xb4\x12\x75\x75\xf7\x48\xbc\xfa\x1b\x3e\x6d\xc9\x5e\xf1\xa1\x52\x5a\xb4\x4c\x26\xaf\x40\x69\xe1\x8e\xe5\x1d\x94\x44\xa5\x73\xbd\x5b\xa0\x51\x2c\x9e\x3d\xcd\xd5\x86\x7d\xf9\xd9\x57\x7f\x77\x26\x09\xcd\xd9\xad\x2c\xe5\x3a\xe4\xb5\x6c\xa8\xfe\xa9\x6a\x06\x05\xb0\x6a\xc3\x9e\x3e\xfb\xec\xf3\x29\xfb\x85\x17\x92\x22\x36\xa3\x20\xea\x81\xfe\xee\x52\x47\xa8\x41\x09\x07\x82\xe3\xcd\x0d\xc3\x6b\xab\xf5\xe1\x81\xd4\xb1\x87\xc0\xce\x60\xc2\xe8\x6e\x8b\x9b\x0e\xba\x31\xec\xd6\x4c\x7b\x66\xe9\xd4\x27\x7c\x0a\xf7\x42\xde\xa6\xa3\xd1\x9f\x7d\xf6\xf9\x17\xe8\x5c\x76\x4f\xdc\x81\xa4\x3b\x05\xfb\xae\x77\x12\xf4\x4f\x63\xeb\x29\x1c\x4e\x17\x61\x18\x6e\x33\x74\xf5\xb9\x4e\x52\x29\x82\x37\xc9\x3f\xf7\x61\xc1\x78\xff\xe5\x9d\xea\x1b\x04\x96\xd2\xf4\xd3\xf0\xfa\xd0\x94\x9a\x0e\x7d\x54\x37\xf4\x36\x1e\xff\x0c\x82\x2b\x79\x99\x87\x72\x89\x45\x72\x42\x74\x11\x16\xb2\x0c\xb1\xe2\xcf\x03\x10\xe4\x44\x7e\x86\x0a\xe7\xbc\x20\xbf\x3b\x25\xc0\xc6\x4e\x08\x17\x54\xdb\x76\x86\xe1\x70\xbe\xf4\x0a\xcf\xc1\xc0\xb6\x52\x26\x5a\xb8\xe2\x7f\x9f\x9f\x39\xa9\xc5\xd6\xe8\x01\xc8\x74\x33\x5a\xb4\x5d\x95\x0a\xd7\x31\x39\x2b\xe0\x50\x08\x50\x71\x1c\xea\xf8\x89\x7f\x58\x82\x62\x0f\xf6\x43\x8a\x8d\xba\xe9\x8b\x63\x5f\x2b\x2e\xea\xa6\xbf\x86\x20\x16\xab\xf1\xdd\x5a\xe7\xb2\xb0\x96\x18\xbc\xbe\x8b\xd8\x60\x92\x81\x6b\xf3\x79\x23\x4a\x51\x5b\x21\xb2\xf0\x20\xfa\xa5\xa6\x8b\x5c\xfb\x55\x54\x30\x92\x62\x6c\xfc\x19\xa7\x50\x37\xac\x90\xa5\x3d\x14\x59\xdb\xc0\xfe\x49\x92\x46\xbc\xd0\x6b\x0e\x47\xce\x02\xc9\xe9\x40\x54\xa8\xfb\x88\xb9\x30\xb5\x73\xc3\x65\xf1\xcd\xd3\x33\x47\x12\x8f\x28\x77\x86\x2c\x25\x31\x5a\x24\x26\xa1\xa0\xa1\xfd\xd3\xf9\x39\xe0\x47\x75\x13\x81\x3e\x3f\x87\xe2\xdf\xe7\xb3\x95\x11\xba\x1f\x3a\x25\xbb\xd8\x37\x68\xa4\xf0\x3d\x00\x3e\x27\xd4\xec\x3f\xe4\x52\x68\xc3\x97\x55\x07\x8e\xc3\x8c\x02\xc5\xfd\x7b\xb2\x64\x6f\xbf\xbb\xfc\xec\xb3\xcf\xfe\xce\xd0\x74\x02\x90\x11\x7e\x5a\x96\x99\xf8\xe6\xa9\xf6\xa8\xd1\x6c\x81\x28\xa8\xf9\x6a\x81\x5e\xe3\xa7\x4c\x43\x4d\x74\xa6\x8a\x5c\xd4\xe8\x9d\x2b\xd5\x7d\x3f\xc4\x67\x9f\x2f\x46\x81\xcc\xf9\xaa\x0b\xef\x40\xab\xa2\x72\xe5\xff\x79\x59\x2a\xb3\xbd\x46\xc5\xef\x7d\x2a\x4e\xee\xe0\xf8\x02\x78\x3e\xd3\xc3\x9e\x19\x37\x9a\x01\x20\xec\x9d\xfd\x1f\x53\x9e\x86\x9a\x53\xfa\xe4\x0e\x8c\x9d\x75\xb9\x01\xa4\x8f\x53\x05\x0c\xe8\x7a\x05\xdc\x46\x18\xf7\xc7\xf0\x43\xd2\x87\x03\xfd\x76\x76\xf9\x13\x76\x3e\x27\x31\x9c\xc0\x62\xff\x81\x73\xf4\xc5\xf4\xb0\xec\xc3\x42\x67\xf3\x38\x41\x2b\x28\x82\xa6\xcc\x45\xbd\xc6\xe4\x38\xa0\x3e\xa4\x08\x99\x2d\xf9\xed\xe2\x6a\xd2\x3d\xd4\x2d\xd1\x73\xbf\xf1\xb8\xa3\xd3\xd9\x99\x1e\x99\xf5\x46\x2c\xf1\xac\xa2\x91\xce\x70\x5b\xf6\x31\x29\x3e\x2f\x04\xe3\x5a\xa0\x68\x0c\xb0\x29\x4a\x80\xb7\xf4\xa3\x8c\x15\x8c\xbc\x09\xfb\x61\x7a\x65\xe4\xf6\xd6\xf3\xb9\xdb\xad\x8c\xea\x62\x80\x6e\x4f\x64\xf2\x5c\x59\xdb\x00\x58\x7c\x4e\x96\x2e\x72\xcb\x05\x49\xbe\xa3\x8a\xc8\x51\x9e\x9d\xaf\xe9\x9d\x52\x07\x66\x61\x5f\x0d\xa9\x47\x1e\xf1\x43\xf2\xb9\x29\x07\x1a\xbc\xaf\xe5\x33\x7e\xd5\x69\x5c\x66\x7f\xc3\x2a\xa8\xe4\xba\x06\x32\xc3\x65\x99\x2b\xad\x2b\x35\x7b\x2d\xee\x44\xbd\x3d\xc7\x9b\xf2\xac\x95\x05\x54\xa9\x7c\xe2\xca\x48\xe0\x50\x76\x02\x60\x83\xba\x9e\x14\xf1\xce\x62\xb1\x76\xc6\x15\xe5\x30\xb7\x7e\xb6\x7f\xd7\x22\x5e\xb2\x30\x25\x50\xb9\x34\x57\x10\xb5\xc0\x21\xbb\x6d\x74\xe5\x07\x4e\x8f\xbe\x2d\xc6\xa1\x79\x86\xfe\xde\x73\x2d\x73\xc1\xf2\x7a\x75\x6e\x27\xd0\x1f\x3c\xbe\x8e\x87\x7d\x50\x5a\xa7\x70\x98\xa6\xa3\xbf\x35\x08\xdd\x7b\xb4\xb0\xaf\x36\xe7\x39\x43\xbc\x4a\x2f\x2b\x21\x2c\x25\xeb\x74\x13\xe9\x21\x9d\xbf\xe1\x22\xae\x4d\x68\xb9\xf4\xab\x04\x76\x7e\x4e\x68\x7e\x83\x53\x3c\xeb\x9a\xf4\x3e\x7f\xd2\x0f\x69\x57\x5a\x24\x42\x9c\x7c\xd8\x6d\x02\x89\xd2\x2a\x71\xca\xce\x8c\xde\xb7\x93\xa1\x6c\x70\x43\x2b\xf6\x90\x07\xf3\xe1\xf2\x8c\xeb\x38\xdc\x2a\xd2\x48\x5c\xd5\x50\xab\x12\x3c\xdd\xb4\x1d\x82\x63\x4d\xe4\x9b\x56\x64\x2f\x2b\x69\x8c\xb3\xce\xd5\x11\xd4\x67\x9c\xb4\x0a\x33\x4e\x18\xfb\x5e\x1a\xbb\xb4\xa5\xc1\xfb\x0a\x61\x32\xa7\x86\x2f\x11\xfb\xf8\x9e\xd1\x95\x3e\x86\xb6\x05\x34\x62\x1a\x26\x00\xa9\x50\x65\x09\x51\x8f\xea\x80\x6b\xac\xaa\xd5\x87\x15\xd3\x2a\xbb\xed\x6d\x0a\xdc\x47\xf6\x2b\xfc\x04\xd1\x6e\x15\x8e\x39\x3f\x6f\x4a\xf9\xe1\x1c\xe1\x7d\xf3\x04\x6e\x4b\x47\x19\x3b\xdc\x61\x82\x60\x55\xc9\x66\x2b\xaf\x66\x82\xe1\x62\xdf\x71\x67\xab\x64\xa8\xff\x9f\x56\x51\x30\xc3\xff\x7f\x8a\x6e\x67\xca\x83\x0c\x70\x2d\x50\x8c\x21\xc3\x9b\xab\xe8\x7a\x00\xf4\x39\x38\xc9\xbe\x7e\xf2\xa4\x50\x19\xb7\x46\xd7\xd7\x17\x4f\x78\x25\xc3\x11\x35\x01\x86\x79\x3c\x98\x66\xc9\xb8\x61\x96\x21\x06\x34\xa5\x97\x48\x53\xe3\x35\xe4\x41\xb9\x05\x94\xfe\x5f\x51\x8f\xbd\x00\x58\xc7\x30\x84\x48\x04\xf5\xa1\xa0\x17\xbb\x32\xcd\xa3\x36\x82\x7d\xf6\xdd\x6f\x2e\xa8\xdb\xd2\x4e\xdc\xb2\x02\x40\xb2\x3b\xed\xb0\x27\x44\x2a\x8f\x60\xd1\x81\x2d\xca\x9d\x9d\x89\x14\xd5\xfd\x42\x2c\xd5\xc0\xe5\x6b\x7a\x04\xf0\x7e\x0e\xf2\xc5\x6d\xe3\x5f\xc4\xf3\x44\xd8\xd4\xc9\x9e\xbc\x81\x8e\x18\xe4\x26\xbe\x74\x1a\x68\xdd\xa0\x78\x1a\x60\xcf\x42\xf6\x49\xab\xdc\x50\x30\x37\xb5\xe1\xd0\x28\x26\xe4\x9c\x07\xbf\x70\xd4\x4b\x23\x7c\x49\x10\xc1\xd9\x46\xb5\xcd\x06\xdc\x90\x78\x83\x2a\x35\x7b\x76\x48\x13\x04\x92\x6c\x0e\xcd\x52\x57\x32\x6c\x60\x26\x7f\x32\xd1\x32\x31\xa4\x75\x24\xde\x67\xf2\xba\x3e\x9d\xb2\xd7\xe3\x51\xb3\x26\xee\xd3\x0d\x10\x9f\x6d\x0d\xf1\x00\x82\xf6\x5a\xdc\x63\x8d\xec\xb8\x21\x28\x85\xe3\x4c\xe0\x3d\xf4\x79\x81\xcf\x50\xcd\xa9\xba\x76\x8f\xe4\x59\x44\x6b\x88\x08\x07\x9a\xfe\xee\x2a\x6f\x43\xb1\xe9\x56\x79\xaa\x10\xbd\x9d\x80\x1c\x2d\x77\x29\x32\x68\xa5\x52\xd9\xef\x10\x47\x85\xe2\x23\x42\xfd\xef\xd8\xdb\xe9\xc3\x63\x5e\xbf\x79\x07\x11\x40\xac\xa9\xf0\x80\x53\x44\x2d\x7c\xf0\xe3\x31\xf6\x65\x6b\xf6\x4f\xe8\xcb\x1d\x89\x4d\x8e\x36\x00\xb2\x1b\xa9\x45\x5a\xf1\x1b\x20\x39\x4f\x33\xb4\x16\x12\xf9\xc4\x19\x2b\xf0\x47\xa8\x6b\x6b\x49\x43\x3d\x80\xc6\xb1\xa3\x74\xc5\xda\x3d\x1b\xfa\xb9\x00\x5d\xb4\x29\x92\x09\xb5\x04\x1a\xf2\xe2\xde\x1a\xf3\xe4\xa9\x44\xdb\x39\xed\xc1\x45\xc7\x09\xfb\x52\x0b\x1c\x95\xa8\x8d\x3c\x11\x2e\x90\x46\x0a\xbd\x11\x20\xbe\xd6\x02\xd9\x09\xa0\x7a\xfd\xe6\x9d\xcb\xbc\x3a\x8d\x94\xbc\x78\x7d\xed\xc3\x2c\x7a\xb8\x5f\x0a\x73\xaf\xea\xdb\xdf\xed\x7b\x3e\x1d\x8c\x0c\x8c\x27\xc2\x64\x4f\xac\xd9\xa8\x21\x74\x47\xd2\xbd\x1f\xd0\x81\xe2\x36\x7e\xfb\x51\x96\xcd\x87\x37\x65\xb1\xfa\x7d\xc4\x92\x4b\xfd\xe4\x71\x35\x1e\x38\x48\xfa\x60\xba\xd0\xd6\x47\x15\x77\x61\xb0\x9c\xe2\x51\x1c\x32\x2e\xf9\xf8\xd6\x87\x4f\x4c\x7d\x08\xb4\xe4\x11\xfa\x1d\x6a\x7e\xde\xa5\x26\x11\xe2\x49\x5e\xf6\x93\xd0\xce\xfc\xe5\x07\x23\xea\x92\x17\xaf\xed\xd9\x91\x42\xe6\xfa\xb4\xd7\x3a\xa2\xda\x9f\x3a\xb0\xfc\xbd\xea\xe8\x36\x78\x51\x75\x14\x11\x41\x9a\x26\x1a\xbd\x4d\x48\x77\x84\xe6\x79\x5e\x0b\xed\xb8\x09\x77\x7f\x08\xcf\x92\xed\xf2\xf5\xf3\x9f\x5e\x92\x03\x36\x06\x8d\x5b\x46\xf4\x72\x48\x78\x9b\xf8\x83\xb9\xcb\xd2\xc4\xe1\x14\xd6\xa9\x7f\x7d\x4d\xa1\x5f\x4e\x7a\x7c\x6c\xc6\x25\x39\xc9\xa2\x0b\x4c\xb3\xaa\x44\xe8\xdf\x94\x20\x60\x14\xa3\xac\xaf\x57\x57\x93\xee\x70\x76\x1c\xdf\x20\x0f\x81\xcd\xd0\x7a\xb6\x6b\xeb\x39\xab\x45\xa6\xea\xbc\x2b\x0c\x3d\x85\x45\x36\x09\x43\x44\x50\x66\x25\xcc\x3e\xda\x51\x0e\xc0\xe1\x6c\xff\xf1\x03\xc1\xd9\x72\x4d\x79\x99\x58\x08\x9e\x43\xb1\xab\x44\x38\xe8\x42\xaf\xdb\x2f\x11\x2f\xe5\x5c\x96\x62\x1c\x31\xe8\x8a\x22\x51\x5f\x40\x37\x3f\x57\xa3\xac\x99\xe5\x6a\xc9\x5d\xe3\x10\x1e\xc6\x2b\x13\xf9\xf3\x21\x78\x2d\x19\x94\x46\x33\xa8\xd8\xc8\xac\x69\x85\xee\x22\x02\x58\x12\xc0\x7b\x51\xc0\xdd\xa1\x1f\x39\xb0\xd1\x05\x21\x3a\x6e\x62\xf3\x0f\x6e\x70\xf0\x03\x73\xd6\x4f\x75\x5f\xd6\x5e\x7b\x9a\xfd\xc7\xf2\x32\x0c\x75\x42\x66\xea\xfd\x54\xb4\xd7\xca\xe3\xb6\xb5\x0e\xd3\xda\x7b\x5c\x3b\x46\xa3\x45\x4e\x24\x07\x39\x0e\xa8\xb9\x50\x08\xf3\x15\x65\x0e\x2d\xdd\x74\x74\x37\xd6\x37\x10\x2f\x57\x78\x67\x16\x02\x07\x80\xb9\x21\xd4\x0c\x3c\xb8\xfd\xbb\x43\xac\x38\x2d\x26\xae\x7d\x8e\xbb\x53\x7e\xf1\xfa\x3a\xe4\x2d\x8c\x38\x2e\x6c\x62\xd0\x6e\x76\x89\xe3\x4f\x6c\x88\x3c\x2a\xcb\xe3\xc5\xeb\xeb\x03\x10\xe7\xea\x9f\x2f\x5e\x27\x72\x38\x92\x4c\xf1\x7e\x88\xf5\x8f\x8d\xe4\x45\xb4\x44\x81\x7b\x6d\xc8\x2c\xde\x77\x36\x65\x4a\x0f\x2b\x2a\x88\x6a\xb4\x1f\x16\x61\x97\xf7\xcd\x7f\xfc\x82\x5a\xa7\x54\xba\xf8\x3a\x03\x42\xfa\x73\xab\xac\xbb\xeb\x82\xcd\xa2\xb8\xf7\x78\xc3\xc7\xeb\xdc\xb7\xbf\x78\x03\x20\x9e\xe9\xd7\xec\xb9\x66\xbf\xca\x32\x57\xf7\x9a\x51\x4b\xab\x62\x95\x16\xa6\xf1\x65\xc4\x01\x43\xb8\xaf\xfc\xe7\x8b\xd7\xba\x9b\x81\xfb\xd5\x0e\x2b\xa0\xd1\x46\x2d\xad\x80\xa1\x5b\x63\x24\x8f\x7d\xe2\x33\xf9\x42\x80\x88\x56\x92\xed\x3b\xc0\x5f\x6a\x58\xba\x85\xef\x05\x76\x88\x17\xaf\xaf\xa9\x4e\x18\xd7\xec\x35\xd4\x58\x28\x73\x87\xa5\x05\xee\x47\xc4\x74\x04\xbc\xf3\x59\x39\x6d\x1e\x0f\x8d\x97\x31\xbc\xce\x16\x98\x66\x44\x2c\x1c\xd7\x0f\xde\x95\xfb\x03\xa8\x9d\x71\x43\x54\x55\xb8\x52\x88\x2e\x7f\xf7\xe3\xcb\xab\x12\xca\x8f\x0c\x94\x26\xf0\xdc\x88\x5e\xeb\x70\xc5\x95\x69\x88\xdf\x09\x75\x08\x46\x58\x75\x67\x74\xe5\x6c\x28\x2b\x65\x5d\x25\x82\xf1\x85\x08\x3a\xf0\xb6\x2b\x43\xd0\xf9\x7c\x6d\x12\xbf\xc4\xb9\x8b\x31\x35\x02\xfa\x10\xdb\x12\x78\x6f\x41\x80\x6e\x31\x00\x80\xba\x75\x41\x00\x3f\x5c\xbb\xec\x41\xb8\x41\x74\x23\xbb\xe0\x89\x92\x3a\x40\x8f\x49\xd3\x77\xc2\x48\xc3\x0c\x08\x24\x56\xe9\x18\x27\x95\xfe\x5d\xb6\x49\x36\xe1\x4d\x4c\x3c\xdf\xae\x58\xc6\xf9\xc1\x45\x74\x00\xe2\xb1\x84\xf4\x3c\x66\x6d\x66\xc9\x10\x8b\xd3\x41\x44\xb5\x3b\xc4\x68\x79\xc5\x58\x85\xed\x0b\x58\xec\x20\x6f\x80\x58\xd7\xbb\xe8\xe6\x39\x61\xb2\x34\x35\xde\xf5\x2f\x8c\xa9\xd6\x89\x5f\xf8\x8a\x7d\x5f\xf3\x12\xba\xe9\x5e\x2e\x44\x76\xab\xbf\xc6\xb0\x03\xd7\x79\x90\xaa\x13\x61\x59\x54\x0b\xfe\xbc\xf2\xb9\xb6\xcb\x65\x53\x92\x33\xfd\x6b\x18\x91\xfd\xf6\x5a\xe5\x22\x96\xc7\xd1\x07\x29\xa5\x8d\xf8\x20\xb2\x10\x0f\x62\xcd\x3f\x5e\x61\xd5\xc6\xb9\xdd\xf1\x0b\xf4\x53\x98\x0c\xd2\xf5\xe0\x9e\x5c\xbb\x43\x16\xa5\x0d\x40\x26\xdc\x95\x83\x00\x59\x6d\x3c\x33\x18\x92\x7d\x2f\x66\x74\xbd\x07\x59\x74\xd6\x1e\xc1\x50\x6e\x8c\x26\xab\x8d\x66\x7f\xbb\xf8\xdb\x05\x1a\xac\x59\xe5\xfd\xc5\x7f\xbb\xf8\xdb\x53\xf8\xb1\xc9\x2b\xaf\x9d\xdd\xa5\x26\xd9\x36\x55\xad\x3e\x48\x91\x94\x3e\x66\xaa\x8c\xe2\x2c\xf0\x52\x02\x60\xaa\x39\xa4\x95\x90\x03\x32\x04\x95\x8b\xcc\xdd\x51\x04\x4c\x5b\x91\xc4\x35\x44\xaf\x71\x24\x35\x88\x23\xdd\xa7\x80\xed\x8f\x91\x6d\x09\x4e\xab\xc8\xea\xa2\xc5\xe1\x2c\x65\x17\x06\x90\xb4\x1d\x4f\xb6\xf7\x69\x9a\x53\x8c\xe4\x74\x7d\x07\x80\x1f\x3e\xaa\x47\x11\x6a\xf1\xc9\x04\xf0\xb3\xa6\x8a\x2c\x5b\xe1\x42\x4b\xfe\x81\x9a\x31\x42\xec\x69\xf0\xb9\xd6\x42\x5b\xcb\x1c\xf2\xdb\xa0\xd5\x0d\xc4\xe4\xc9\x7f\x37\xc1\x79\xd3\x3d\xcc\x4c\x36\xb4\x98\x8f\xf4\xc0\xa8\x95\xd3\xe4\x27\x5e\x38\x4d\xfe\xe7\xba\x39\xcd\xba\xb1\x94\xfe\x73\xd9\x1c\x67\xd9\x58\x9d\x34\x71\x21\xd2\xf9\x5a\x27\xeb\x4e\x4b\xc8\x02\x5d\xbf\xf5\xc4\xa7\xe2\x3f\x97\xd3\x47\xb2\x0d\x61\x84\xb8\x87\xa5\xcd\x5f\xab\x5a\x19\x95\xa9\xe2\x1b\x93\x55\x9f\x32\x9f\xe5\xb1\x61\xd1\x6d\xbd\xe0\x92\xd4\xfb\xde\x45\xb7\xcb\x82\xc3\xcc\x10\xbf\xe8\xa2\x72\x7f\x52\xb3\x25\xaf\x6f\x45\xce\xbc\x9c\x32\x48\x44\x80\xfb\x04\x5a\x12\xbe\xca\x15\x5a\x9b\xc0\x3e\xe4\x16\x24\xb3\x56\x05\x37\x56\x88\xa9\x32\x3d\x79\x43\x46\x78\xb0\x3e\xc2\x35\x0d\xbb\xe2\x9f\x4b\xfa\x8f\xb5\xa4\x9b\xfc\xcf\x25\x7d\xaa\x25\x0d\xd1\x97\x13\xca\xa2\x6b\xf9\x60\xd7\xad\x64\x8c\xda\x0c\xe5\x32\x22\xa7\xfe\x87\x95\x2f\xe0\xc3\xd3\xb2\x25\xb0\xb8\x36\xc5\x6e\x42\xeb\x16\xb8\xf7\x80\xbc\xfa\x96\xd8\x18\xc5\x64\x79\xa7\x6e\x05\x63\x4f\x00\x69\x87\x2c\x23\x89\x72\x1c\x7e\x02\x42\xfe\x84\x62\x2e\xa3\xf2\xda\xbe\x1a\x93\x15\xfd\x82\x32\x66\x89\x61\x1e\x98\x13\x34\x90\x1a\xab\x03\xb6\xb8\x00\x80\x21\x87\x8a\x69\xf9\x11\x0a\x6e\x44\x99\xad\x26\x50\xec\x49\x2f\x54\xd1\xdb\xc1\xc7\xd3\xbb\xfd\xbd\x76\x00\x1c\xe1\xa9\x10\x18\x78\x2c\x16\xf2\x66\x63\x60\xf3\xdb\xa6\x64\x4f\x2f\x2e\x98\x34\xde\x45\xe4\x2a\xd2\xf6\xb4\x6b\x89\x33\xbe\xe1\x96\x85\x37\x54\xbd\x8e\x32\xef\x97\x82\xfb\x2e\x81\x50\xc1\x57\x1a\x66\xf8\x2d\x5d\x4c\x78\x2f\x55\x6c\xc3\x3a\x23\xd9\x93\xc4\x67\xf6\xc7\x6f\xb9\x5c\x12\x5f\x36\x05\xf4\x96\x86\xde\x9a\x84\x37\x68\x3d\x5e\x19\xf0\x1b\xdb\xe1\xd2\x79\xf9\x26\x40\x28\x49\xe9\x77\x1a\x57\x1b\xf5\xf2\xb0\x8a\xe3\x8b\x0b\xb3\x98\xb0\xbf\x5f\x98\x05\x60\xf8\xf7\xbf\x9b\x05\xab\x44\x9d\x89\xd2\x48\x1a\x9d\x62\xb0\xbc\x26\x11\xb5\xe7\x86\x2f\xca\x86\x8d\x52\x58\x21\x67\xa2\xc6\x4e\xac\xc2\x44\xbc\xb6\xc4\x7e\x76\x81\xd4\xb1\x23\x46\x43\x78\xcd\xff\xc5\x45\x88\xd0\xf9\x7b\xfa\xce\x16\xe2\xe8\x0a\x34\x11\x86\x03\x82\x39\xf1\x19\x4e\xab\x4a\x4c\x42\x60\x86\xa5\x4c\x1c\xdb\x32\x42\x46\xfb\xd2\x71\xb3\x10\x19\xe2\x23\x42\xc2\x20\x2e\x73\x39\x09\xa2\xd9\x32\x76\x46\xcd\x11\xb2\x07\x3a\xf5\x6b\x66\xcd\xe5\x04\xde\x5a\xad\x18\xd7\x54\xc3\x35\x9d\x79\x12\xdd\xf2\xb3\x0f\x0c\x4b\x23\x5b\xd6\x12\x8b\xe1\x05\xb9\x01\xe9\x87\x58\x1c\x0a\x9e\x81\xdc\xde\x38\xd2\xc7\x61\x4b\x1e\xe7\xfe\x8b\x94\x64\xf3\xf2\xb2\xb6\xb0\x06\x86\xd6\x2a\x93\xb0\xf3\xf7\x90\x60\x30\x84\x08\xfd\xa9\xaf\xae\x7c\x10\x11\x44\xb5\x9b\xa6\x2e\xd3\x4b\x37\x88\x19\x84\xb2\xa9\xe1\x92\x1a\x56\xad\xab\xf8\xe0\xfa\x39\x25\x93\x1a\x51\xe7\xbf\x25\xa6\xe3\xc4\xf3\xe5\x50\x1c\xd1\x21\xc5\xb3\xc3\xc9\x78\xa0\x5d\xc5\x33\x06\x3a\x49\x28\xe8\x08\x07\xd7\xcd\xad\xb5\x91\x94\x7a\x04\x51\xf5\x25\xfd\x3a\xf2\x19\x2b\xcf\xce\x3c\xda\xc4\x62\xc8\xef\xa5\x82\x7b\xd0\xe4\x4d\x10\xd3\x49\xb4\x32\xc0\x56\xfa\xdb\x45\x1c\x57\x02\x3f\x59\x55\xf5\xee\xf2\xca\xfe\xee\x4c\xb8\xa4\x0a\xdd\x1a\x89\x1e\xb5\xf2\xa8\x6f\x5c\x20\x44\xbc\x2f\x33\x15\xd9\xc1\xaf\x5d\x2c\x4c\x00\xa5\xca\x20\x9a\x31\xd6\x27\x13\x4d\x7b\x20\xb9\xc2\xcc\x95\xa3\x4a\xa6\x1b\xe7\x23\x16\x4c\x37\x05\x2a\x58\x3e\x46\xf0\x26\x1d\xc9\xf3\xaf\xa4\x52\x47\x97\x7a\xb1\xe4\xf9\xc3\x97\x27\x05\x04\x2b\xd7\x68\x78\x9e\x69\x86\xe2\x43\x25\xf4\x61\x0f\xf7\x53\x8c\xb8\xca\x10\x8f\x20\x72\x5e\xd7\x46\xf4\xa8\x55\x13\x6d\x1d\xae\x50\x78\x57\x3f\x7b\xb9\x46\xe3\xbf\x4f\xb6\x31\x49\x2f\x92\x6f\x7a\xe1\x0a\xcc\xd8\x04\x20\x94\x9f\xea\x87\x9a\x4c\xd1\xcd\xe6\x68\x8b\xc2\x0b\xe7\x11\xad\x89\x84\x25\x07\x32\x26\x3c\x61\xb6\xb1\x25\x0e\x21\x57\x2d\x99\x4a\x74\xdf\x18\xb9\xea\x59\x72\x23\x29\xb5\x9f\xb9\xd2\x5e\x66\x30\x8d\xc4\x4e\x09\xa2\x1b\x59\x2c\x21\xe7\x38\xa8\xfc\x49\xe8\xa4\x08\x50\x3d\x69\xc2\x5a\x01\x49\xcd\xc7\x58\x39\x43\x16\x0e\xde\x94\x3f\x1e\x2b\xc7\x4f\x32\x94\x90\xdf\x69\x81\x38\x81\x76\x8e\x34\x8b\x7f\xc2\x76\x37\xc1\x91\x0b\xc3\x6a\x59\x8f\x9b\xaf\x4c\x06\xea\x48\x40\x21\x52\x50\x30\x12\x9a\xd3\x60\xe9\x01\x4a\x30\x73\xa1\xe4\xd4\x33\x81\x52\x3e\x7b\x62\xf4\x38\xc8\x0c\x08\x41\x7b\x20\x1f\x63\x4a\xc7\x41\x7f\x40\x72\x4e\x01\x5c\x50\xed\xfb\x11\xc4\x4f\x95\xe8\xee\x3a\x63\xb2\xa4\x7d\x8c\x97\x81\x81\xec\xd5\x95\x8e\xbd\x58\xc7\x50\x85\x41\xfb\x81\x32\xd4\x42\x63\x17\x9a\xf9\x5c\x96\x96\x60\xb0\xf5\x95\xbb\xf2\x5a\xdf\x4b\x28\xef\xd2\x86\x3a\x57\x75\xba\x6e\x3c\xcb\x77\x08\x0c\x6c\x2b\xc6\x4f\x1c\xd4\x4f\xe2\xf0\xae\xae\x5d\xd8\x6b\x10\x9e\x9d\x69\x87\xee\x73\x87\x6d\xa8\x58\xf6\x09\x66\xa0\xbf\xba\xfa\x64\xc7\x13\x1c\xb7\x20\x48\xc9\x7c\xd2\x67\x4b\x92\x5e\x89\xd7\x04\x14\x30\xa1\x58\x5d\xf4\x8e\xe2\xfd\xdc\x86\xbe\xa8\xd6\x3a\x8a\x92\xa9\x3e\xa3\x7a\x33\xb5\x08\xe5\x71\xec\x78\xb5\xab\xce\xe6\x2a\x37\xad\x52\xcd\xac\xa8\x93\xaf\x8f\xe7\xa6\x40\x5d\x28\xc7\x80\x65\x3b\xa8\x5f\x0a\xb8\x2c\x44\x69\xda\x36\x56\x82\x6d\x49\x4e\x43\x95\x63\x10\xf9\x6d\xd8\x19\x46\xd8\x66\x3d\xdc\x71\x1b\xc5\x27\x56\x4c\x3f\x19\x71\x54\x9d\xba\x08\xdd\x04\xf1\x25\xcf\x45\x5c\x88\x3c\xda\x1f\x61\x67\xc4\xad\xd1\x52\xcc\x5b\x82\xfd\x41\xd6\x48\xad\x38\x5b\x23\xa4\x98\xb8\x80\x69\x22\x21\x65\x51\x12\x42\x43\x53\x2c\x56\x71\xc2\x18\xb4\x6a\x4a\x24\x71\xd2\x3d\x77\x0f\xe0\xc0\x7c\xc9\xca\x2e\x12\xe0\xcc\xb1\x52\x96\xa9\x52\x8b\xac\x31\x92\xa2\xc4\x47\xd8\x83\x3b\xd8\x82\xc9\x19\xac\xdf\x1e\x8c\x6c\xc1\xae\x31\x98\xc6\xd5\x92\xcf\x99\x62\xbc\x44\xe2\xae\xee\x28\x9f\xad\xc2\x96\x36\xa9\xcf\xe8\x5c\xf8\x10\xfa\x33\xf5\x85\x5a\xe5\x97\x05\x27\xc0\x21\x54\x69\x50\x56\xd3\xf5\x1a\x92\xd0\xd9\x45\x4b\xa6\x1a\x32\x1a\xd2\x2d\xed\x34\x8f\x6b\x5f\xb5\xe7\x77\xe8\x58\xf5\xed\xa7\xf6\x68\xf2\x5d\xd5\xb7\x87\xda\x6b\x3b\x9b\xfb\xc8\xbe\xbd\xda\xa3\xbb\xc0\x21\xd5\x17\xcc\x27\x69\x46\xa9\x35\xab\xd2\x30\x1d\xf7\x4f\xb5\xe6\xd4\x5a\x9f\x6a\x3a\x8d\x5a\xfa\x4e\xa6\x15\xbe\xdd\xd4\xa0\xe9\x32\xe6\x8c\xbc\x76\xb9\x39\xdb\x68\x24\x6a\xc5\x90\x38\x48\xe2\x44\x62\x9f\xf0\x33\x26\xde\xfc\x47\x68\x15\x52\x14\x61\x14\x89\xf6\x8d\x47\x4d\x43\x6e\x5c\x65\x39\xe6\x1a\x26\x62\xdd\x63\x9e\x74\xaf\xb2\xa3\x26\xd3\xf5\x27\x35\x0f\xc9\x4a\x03\xcd\xbc\x63\x34\xf7\x04\x0e\x1d\xd0\x68\x76\x72\x1c\x8a\x45\xaa\x66\x2b\x3f\x1b\xe4\x7c\x77\x21\x23\x20\x2c\xc1\xf9\xf1\x5b\xd1\x94\xb8\x31\x30\xc9\xb0\xab\xec\xb0\x8f\x74\x2c\x6d\x1d\x89\xce\x06\x4b\x9b\x62\x10\x46\x6f\x35\xa4\xab\xc7\x59\xd9\x63\xb7\x1a\xaf\x56\xc7\x59\xd9\x63\xb6\x9a\x9e\x0d\x75\x8d\x81\xdb\x52\x8d\xeb\x0c\xdb\x2d\x35\x70\x98\x4d\x53\x1a\x59\x38\x86\x53\xf1\x36\x84\x88\x3f\x4d\xc2\xab\x9e\xe1\x16\x0f\x2a\x22\x18\x8a\xac\x03\xd9\xdb\x1b\x50\x8c\xbf\xcb\x01\xdb\x47\xbd\x77\x2d\xd6\x01\xa8\xdb\x58\xad\x9d\xad\x81\x84\xfe\x81\xad\xd6\x53\x2a\xb0\xc7\x6e\xc6\x6e\x52\x53\xeb\x55\x54\x8f\x7b\xbf\xd7\xdc\xdd\xd6\xd4\x75\xab\x79\xcb\x53\xfe\x46\xfd\xe3\x22\xb1\xb6\x3b\xe5\xef\xa8\x7f\xc6\x29\x99\x75\x0a\x06\x80\x8e\x57\x32\x4c\x7c\xa8\x64\x6d\xd5\x3b\xd5\xf7\xec\x55\x34\x6e\x5d\xef\xa8\x6c\xd6\x2b\x1a\xbf\x05\xad\x57\x36\x5b\xd9\x91\x08\xf3\x18\xca\x62\x0b\x63\x67\x7f\xf5\xe0\xd4\xc2\x80\x43\xf8\x63\xb1\x6b\x0e\xe5\x1d\x1c\xe9\x19\x4c\xec\x15\x3a\xe2\x1d\xcc\x2b\xe8\x92\x9d\xb7\x3b\x1e\xf3\xa3\xf9\x05\xd7\x59\x2c\x5d\xb7\xd2\x47\x72\x66\xfc\x0f\x71\x85\x1d\x41\x51\xc4\x66\xfd\x63\xb5\x1f\xfe\x74\x83\xed\xe0\x06\x8b\x8f\xfa\x87\x5c\xca\x61\x19\x77\x57\xde\xbe\xe7\x83\x78\x29\x02\xf4\x93\xba\x7f\xba\x9e\x9f\x6d\xd6\x59\xd8\x09\xb3\x06\xbc\x82\x71\x1f\xbb\x4d\x4e\x9d\x6f\x57\xde\xc3\x44\xea\x3f\xd4\x2b\x09\x9d\xf7\x92\x86\x25\x75\x74\x71\x82\x85\x6e\xf1\xf5\xb3\x64\xcb\x6f\xd5\xdb\x27\x50\xdb\x87\x98\x0e\xaa\x2d\x1f\xb4\xbc\x0d\xad\x50\x14\x39\x9b\x71\x2d\xb3\x10\x24\x0c\xe2\x38\xa6\xbb\x5c\x7f\x75\x35\x9e\x86\x1b\x5b\x63\x95\x97\x2b\x48\x3e\xe9\x56\xf5\xc1\x1d\xa9\x29\xf1\x6c\xb2\x50\xf7\x4c\x2c\x2b\xb3\x8a\x8b\xf7\x3c\xcf\x5d\x5c\x7b\xcf\x45\x63\xa7\x4a\xd0\x1d\x75\xae\x72\xea\x06\x60\xba\x7b\xc7\x10\xda\xed\x82\x7e\x31\x2b\x04\x3b\x49\x79\xbd\x81\xed\x10\xa0\x29\x06\xae\x74\xcc\x37\x11\xe1\x0e\xdb\x55\xc0\xb4\x80\xaf\xda\x20\x66\x2a\x84\x74\x87\x03\x3f\x20\x06\x38\xc3\x56\x90\xa9\x1a\xbd\x83\xb9\xd3\x62\x6e\x1a\x0e\xc9\x29\x7b\x53\x66\xee\xde\x10\xba\xa9\x50\x31\x1e\x57\x22\xd1\x2c\xa8\xd7\xb9\x9a\x77\xc2\xea\x01\xa2\xa3\x45\xee\x09\x01\xad\x54\x70\xce\x5e\xe9\xcc\x65\xad\x4d\x94\x87\xe2\xfb\xae\xd0\x94\x08\x0f\x3b\x2b\xe7\xcc\x49\x0a\x7a\xb6\x29\xeb\x95\x59\x4b\x25\x01\x63\x8f\x21\xf2\x28\x76\xcb\xa6\x30\xb2\x2a\x88\xa5\xdb\x2f\x03\xfc\xde\x2a\xb5\xd6\x5c\x76\x5f\x09\xe6\x5e\x11\xb1\x67\x8d\x61\xa5\x42\x81\xb0\xa4\xf3\x5d\x54\x22\x42\x01\x71\x57\xf6\x08\xde\xed\x4f\xd6\xb3\x42\x5a\x8c\xf7\x0b\xe5\x2a\x2c\x14\xe0\x2c\xf1\xac\x73\xd3\x8b\x22\x5c\x46\xc9\x01\x6e\x4d\x58\x08\xae\x1d\x2f\x66\x6e\xb4\xd6\x42\xba\x95\x83\x68\x0e\x0d\xe0\xd7\x42\x84\xe7\x0b\xac\x43\x1b\x64\xcf\x81\xec\x5d\xd0\x84\x67\xb1\x4a\x33\x19\xd2\xe1\x61\xc5\x46\x70\xf1\x67\x17\x19\xd3\x01\x0c\x95\x24\x4a\x75\x8f\x4b\x71\x80\x9e\x7b\x4b\xea\x4b\x87\x6b\xb7\xda\xec\x36\xe2\x09\xe1\x3f\xa6\xd3\xa7\xbb\x0c\xf0\x47\xd7\x89\xa5\x0f\x26\x29\x29\x3b\xd5\x62\xdd\x83\x70\xb3\x15\xec\x52\xec\x37\x43\x25\xf2\x38\x95\x77\xe5\xbe\xc7\x48\x7c\x71\x07\xf7\x2d\xb0\xdd\x41\x30\xa1\x4e\xa1\x63\x6a\x8b\x46\x2d\x96\xd6\xa5\x85\x21\x5e\x5d\xdd\x7d\xee\x03\xca\xb8\x17\xb1\xee\x90\xd8\x7b\xc9\x6f\x26\x83\x03\xc6\xaa\x73\xb6\xc2\xce\xde\x7e\x1e\xd8\x97\x1b\xfb\xf4\x85\xdd\x21\x2e\x59\xbc\x65\xe7\xee\x0d\xb2\x81\xb5\xab\x7e\xe2\x2e\xad\x53\x94\x77\xb2\x56\x25\x34\xca\x9c\x4b\x51\xf4\x35\x39\xb1\x27\xa7\xdf\xc3\x97\xd1\x45\xbb\xb5\x0b\x9b\x25\x98\x7b\x77\x92\x27\xc0\xee\x78\x2d\xe1\x41\x27\x6f\x73\xc4\x25\x57\xb7\xda\x15\x48\x51\x0f\x74\x68\x8d\x0e\x6b\xc8\x65\x1d\xe2\x2f\xde\xb7\xee\xd1\x9e\xb2\xe7\xd1\x1c\xf0\x2d\x6f\x41\xc1\x29\x42\x5a\x80\xce\x52\xf2\xdb\x52\x34\xec\xf8\xac\x3c\xac\x76\xb5\xe4\xd5\x36\xf4\x77\x93\xea\xdd\x44\xc6\xf2\x00\x57\x58\x00\x7a\x20\xf2\x27\x30\xe3\x74\xbb\x98\xbe\x45\x11\xfe\x74\x86\x40\x23\x82\x29\x12\xf5\xc7\xd6\xfd\x33\xef\x90\xff\xb0\x24\xc7\x2a\xbc\x56\xed\x9e\xdf\x8a\xd5\x78\x32\xcf\xb9\x2c\xa2\xe0\xcb\xf0\x3c\x00\x64\xb7\x62\xb5\x81\xac\xcf\x8d\xb1\xaf\x26\x51\x9c\x2d\x50\x56\xcc\x1d\x34\x8a\xab\x8c\x8f\xbc\xe8\xac\xe5\xb2\x18\x53\x27\x79\x34\x5d\xd6\x6f\x0f\xfd\x14\xb1\x86\x41\x48\x05\xed\x01\xb5\x0f\x2d\xa6\xec\x0a\xfb\xe2\x2d\x42\xce\x73\xf4\xf0\x3b\x61\xb2\x85\xb3\x5e\xe1\x44\xe9\x87\xa7\x54\xde\x39\x24\x9a\x7a\x6d\xfc\xed\x0a\x8b\x9f\xbb\x0b\xf7\xe4\x1b\x0d\xcb\x86\x3a\x86\x92\x41\x6c\x3f\x57\xb5\x8f\xe2\xf0\x1b\x4a\x18\xc8\x29\x72\x6d\xb8\x91\x99\xeb\xa2\x59\xe6\x3e\x24\x03\x44\x1f\x58\x98\xaa\x21\x5f\xd4\x33\xda\x12\x2e\x43\x51\xa8\x11\x1a\x7e\x13\x5f\x5f\xa8\xfb\xf2\x9e\xd7\xf9\xf3\xab\x57\x93\x54\xbf\xab\x9a\x5d\x5e\xfd\x0c\x68\x2e\xc5\x52\xb9\x24\x68\xdc\xe6\xa2\x5b\x86\x7e\x19\x70\x70\xe3\x3a\x7a\xee\xd4\xeb\xd7\xeb\x99\xdd\xdc\x00\xe8\x34\xab\x9a\x27\x38\x8c\x37\xb2\xbc\xef\x20\x3c\x23\x55\x60\x55\x80\xde\x3a\xc7\x3f\x41\x89\xcc\x09\xe8\xcd\x6b\xa7\xe9\x32\xcb\x21\xc5\x1b\xc7\x72\x3f\x51\xc2\xa6\x95\x5e\xc0\xad\x5f\x17\x71\x68\x85\x88\x29\xaf\x3b\xab\xa5\x9c\x50\x7c\xcf\x2b\xb9\x15\xa7\x9c\x43\xe0\x48\x1c\x73\xe0\x3b\xcc\x0a\x5b\x27\x36\x3f\x47\xbf\x79\xff\x56\x7e\x60\xf6\xd0\xdc\x3e\x06\xee\x40\x63\x4c\xd9\x5b\x28\x6a\x23\xe9\xe1\x5b\xc8\x92\x20\xb3\xc6\xce\x6a\xa7\x8d\x7a\x90\xc0\xee\xf0\x11\x2a\x28\x80\x71\xa7\x07\x37\x5e\xf2\xe6\x61\x8d\xd0\x18\xc3\x5e\xab\x2b\x54\xf0\x84\x4f\xe0\x68\x79\x27\xd1\x80\x0a\x7c\x41\x4b\xfb\xf4\xbc\xb1\x68\xfd\xfc\xea\xc5\x4e\xbc\xa9\xf0\xdb\xf5\x5a\x69\x5f\xce\xd8\x01\x22\x21\x1f\x34\x02\xd9\x03\x0b\x79\x09\x09\x83\xa1\x1e\x35\x64\x6b\xee\x26\xf3\x96\xae\x7d\xe0\x42\xf2\x0e\x65\x06\x1e\x61\x33\xd8\x73\x31\xd8\xcf\x5f\x0f\xa0\x3e\x7e\x7d\xa0\x3d\xdc\x59\x23\x47\x62\xeb\x95\xca\xdf\x89\x65\x55\x40\x31\xca\x9e\xfe\x3b\x83\x3c\x8c\x3e\xd4\x1b\xfa\xf7\x80\x67\xd4\xbf\xbb\xc1\xdc\x73\x6e\x0e\x4b\x92\x30\x40\xa8\xf0\xed\x8e\x19\xd4\x22\xde\x59\x60\xd8\x96\x29\x0e\x29\x98\xab\xa6\xcc\x43\x33\x16\xd7\x2a\x72\x08\x7c\x5f\x5b\x17\xd7\xd2\x05\x8f\xd7\x01\x12\x1a\x75\xba\x85\xc3\x16\x26\x59\xa5\x72\x4f\x90\x35\x1c\x19\x61\x6f\xf7\xb1\x01\x4d\xee\x96\x3b\x26\x79\x71\x7b\x93\x3b\xfa\xbc\xcf\xe8\x4e\x1e\x77\xcc\xee\x78\x4a\xe3\x0d\xef\x04\xe3\xf1\xa6\x77\x3c\xd8\x48\xe3\x1b\x20\xbe\x6b\x7d\xdb\x32\xbf\x0f\xc4\xdd\x1f\xad\xe5\xf2\xd6\xce\x7a\x12\x8a\x28\xf7\x70\x57\x67\x0b\x91\x37\x85\x2c\x6f\x7e\x8f\xbe\xe9\xb4\xf9\x8d\x1e\xc1\xba\x20\x63\x4d\x7b\x43\x9a\x2e\x27\xa1\x46\x17\xf4\xee\xb7\x7a\xce\xbd\xc5\x78\x55\x15\xd2\xae\x8c\x11\xc7\x7c\x74\x9a\xc0\x80\x35\x0c\x68\xc1\xdf\x89\x1a\x4b\x85\x07\x69\xa0\x45\x1f\x5e\xa4\x62\xb7\xb1\x40\xb4\xa1\xe0\x35\x80\x03\x13\x9e\x4e\xc3\xd0\xe0\x99\x86\x39\x86\xda\xd3\xae\x18\x86\xbb\x46\xf0\x57\xa6\xd1\x2b\xb5\x70\xb3\x74\x1e\xd9\x00\x7e\x44\xa8\x72\xe0\xc3\x13\x30\x3a\xdf\x23\x5e\x6d\x97\x3f\xbe\x25\xea\x49\xec\x4a\xb5\x36\xea\x06\xd6\xfa\x0f\xaf\x6a\x91\xcb\x0c\x17\xe7\xb5\xa8\x25\x2f\x7e\xf7\xd3\xd2\x3d\x40\x19\x29\xd6\xa8\x0b\xbd\x35\xc0\xef\x7d\xeb\xf3\x8d\x35\x96\x3c\x16\xd1\x2d\x10\xb8\x2f\xa4\xbb\xda\xa5\x31\xfd\xcd\x31\x95\xb3\xf9\x89\xdb\x75\x0a\xe5\x76\x78\x26\x47\xdd\x98\x44\x54\xac\xfc\x44\xd7\x10\x11\x0e\x14\x7e\x89\x43\x0b\x14\x14\x9f\x03\xd0\x12\xe8\x65\x2d\x86\x6b\x82\xef\xfc\xbc\xb5\xd0\xd4\x13\x43\xce\xfd\x98\x1b\xab\xba\x87\x9e\x73\xa0\x5c\x28\x07\x15\x26\xf0\xff\xdc\x7e\xcd\xee\xfe\x5f\xd8\x76\xca\x44\x93\xba\x3d\xac\x83\x05\x45\x34\xb8\x0f\xa1\x2c\x1e\x06\x07\x08\xc7\x16\xba\x62\xa3\x89\xdb\xb5\xeb\x7b\x87\xc4\xe0\x70\x02\x64\x1c\x82\x07\x3b\x4e\xb8\xf5\x5f\xfb\x6b\x14\x8b\x70\xe7\x6e\xfc\xe0\x9c\x2c\x95\x79\x10\x6e\xc6\xe3\xee\xe2\xd3\x4c\x28\x4b\x4c\x72\x0e\x64\xc0\xc0\xc7\x1d\x84\x76\x3d\xbc\xaf\x76\xd9\x94\x5d\x4b\xba\x33\xb5\x2b\xb6\xb6\x92\x82\x61\x65\x01\x3f\xd4\xa4\xd2\xd8\xb9\x3a\x96\x87\xe8\x0c\x2a\xb4\x11\xf8\x7f\x58\x9e\x41\x5d\xc7\x1f\x94\x36\xae\x02\x01\xbb\xa2\x00\x3d\x44\x10\x1f\xbe\xba\xd2\x51\x98\xe6\xac\xc1\x7b\x3a\x0a\xcb\x71\x0e\x03\x7c\x91\xfd\xf5\x62\x0a\xff\xff\xe9\x01\x19\x8e\xe4\x83\x1b\x21\x1c\x33\x53\xe5\xbc\x90\x99\x25\x8d\xb9\x17\xa2\x44\xd5\x08\xdc\x83\x90\x95\x45\x3c\x23\x17\x72\xe8\x11\xc7\x1b\x01\xc2\x13\xde\xa5\x72\x0b\xeb\x25\x25\x6c\x49\x3e\x34\xa6\x97\x72\x13\x18\x28\xd0\x8b\x28\x38\x09\xe6\x2a\xd8\x9a\x34\x7f\x7f\x71\x08\x2d\x7e\x40\x84\xe6\x80\x25\x84\xdc\xd8\xed\xdb\x52\x1f\xef\xa5\xda\xb4\x56\x73\x37\x0b\x2a\x36\x0f\x56\x71\x2d\xaa\x5a\x68\x6c\x73\x59\xb8\x6c\x77\x1f\xe0\x33\x26\xcb\x7d\x77\x09\xf2\x52\x6d\x09\x42\x58\x26\x52\x55\x2a\x73\x7e\x04\x95\x80\x12\x42\x12\x59\xaa\xf1\x02\x92\xb2\x6a\x11\x30\x76\x52\xb3\xa7\x60\xb4\xee\x93\x28\x01\x35\xd1\xc9\x71\x7a\x74\x2c\x04\x16\x98\x63\x74\x1d\x28\x28\xa3\xb5\x78\x30\x66\x5a\xe5\x57\xd5\xc2\x9e\x03\xa0\xb8\xa3\xb5\xf3\x42\x5f\xde\xb1\x5c\x72\x9f\x7b\x2e\x85\xdf\x5e\x42\x8d\x4e\xa9\xca\x2b\x4e\x61\x1b\x75\x53\x6a\x17\x66\x77\x2d\x30\x52\x0d\xed\xcb\x18\x13\x17\xa8\x04\xfd\x67\xd6\xb3\xe1\x3b\xd5\xd4\xac\x10\x77\xa2\xd0\x74\x02\x82\x6b\xa3\x78\x08\x34\x9a\x3d\xbb\xa3\x97\x6b\xa9\x6a\x69\x56\x13\x8a\x48\xd5\xa6\x96\x19\x1d\xfd\xb0\x75\xf1\xe5\xd5\xcf\xce\x0f\x89\x61\x00\xbc\x29\xb3\xc5\xd4\x7f\xc9\x9e\xb2\x73\xf6\x59\x64\x5c\xe9\x8a\xdf\x97\x51\xc8\xc3\x5c\x91\xc1\x36\x5b\x85\x8f\x3e\x0f\x85\x32\x3a\x78\xbe\x75\x5d\x8a\x01\x1c\x39\x02\xf0\x1e\x8f\xba\x79\xa1\xb4\xfb\x1e\xc1\xee\x83\x31\x67\x97\x54\x2a\x88\xda\x6b\x36\xf6\x6f\x21\x24\x2b\xf0\x73\x1f\xa9\x08\x6b\x17\x03\xbd\xaa\x18\x2a\x83\x18\xd4\x4d\x67\x56\xd7\xb0\x4d\xde\x40\xe0\xa3\x23\x67\x95\x74\x07\xa3\x56\x56\xb8\xa0\xf0\x46\xae\x04\xbf\x5a\x7c\x12\x03\xeb\x01\x9c\x07\x14\x0c\xe6\x30\x77\xad\xda\x01\x37\x6b\xf0\xa9\xfb\xf6\x50\x10\x01\xe3\xf5\xb8\x55\xb0\x92\x5c\xd3\xf1\x6b\xc7\x60\x47\x44\x56\x2c\xb6\x29\x8d\xcc\x78\xc1\xb0\x66\xf2\x01\x38\x93\xce\xd6\x27\xcd\x45\x2b\x73\xb6\x4a\x86\x1d\xc7\xb0\xe4\x8b\x6d\x38\xe5\x74\xfb\x8e\x9c\xb2\x46\x75\xcc\x28\x87\x87\x9b\xd8\xc1\x78\x14\xee\xf3\x7e\x51\x45\xb3\x84\x36\xce\x1f\x0c\xcb\xb9\xe1\x13\x36\x93\x25\xaf\x57\xf0\x47\x1f\x97\x8c\xaa\xf9\x4d\x72\xa9\x1a\x7d\x10\xdd\xec\x93\x3b\x05\x3b\x66\xdd\xc1\x30\x3b\xf9\xa2\xdf\x25\x37\x97\xbe\x02\x76\xec\x78\xf3\xc8\x03\x87\x62\x74\xe2\xb8\xbe\x28\x4c\x02\xcb\x2e\xe7\x21\xea\xae\x14\xf7\xc5\x2a\x76\x1c\x85\xa2\xbd\x0e\xf7\xa5\x6a\x4a\xe3\xc7\x5f\xf2\xaa\x12\x3e\xa4\x8b\xfa\x96\x81\xfa\x8f\xfa\x83\x05\xbc\xcf\xf4\x66\x24\x69\x3f\x0b\xa5\x58\x2c\x8a\xde\xf6\x56\xa5\x11\x2e\xca\xd4\xfe\x00\xe8\x88\x1c\xd8\xaf\xd7\x35\x25\x7b\xb6\xf9\x0e\xf6\x3d\x4e\x71\xb3\x94\xb8\xf6\x41\x51\xf3\x29\xf4\x44\x8d\x13\x14\x05\x2c\xe5\x05\x7d\xaf\xd7\x4b\x0b\xca\xc6\x96\x6e\xf4\xf5\xd2\xd2\x13\x31\xd3\x2f\x0a\x68\xbf\x6f\x2b\x0e\xeb\x44\xe1\xd7\x38\x10\x16\x29\x6f\xbf\x8a\xeb\x20\x84\x18\x2c\x67\x6e\x47\xef\xb5\x85\x24\x12\x90\x18\xec\xb0\x90\x24\xd8\x3c\x2f\xb4\x42\xe7\xb1\xfd\x49\x1a\xb1\xfc\xab\x7d\xe7\xd3\xc8\xe9\x8c\x8a\xcc\x43\x72\xd4\x6c\x95\x1b\xe7\x4c\xd4\xb5\xaa\x23\x59\xb5\x04\xf1\xf0\x76\x08\x80\x19\x2d\x8c\x2e\x4c\xda\xd2\x7e\xc0\x4e\xef\x8a\x60\x6f\xe4\x51\x08\x58\xdd\x4f\x55\x5d\x76\x62\x41\x26\xa9\x8b\x05\xa8\x03\x4c\xd1\xf6\xa8\x8e\x23\x61\x94\x5e\xd5\x80\x6b\xd6\xf3\x92\x1e\xa2\x2d\x08\x9a\xd5\xa8\xa8\xfd\x60\x14\x50\xb2\x59\xe4\xdd\xed\xc3\x21\x34\x20\x8e\x47\x9b\x03\xf3\x22\x47\xa9\x17\x20\x68\x51\x36\x45\x8e\xf1\x52\xce\x29\x2b\x69\x13\x85\xd7\x96\xe0\x61\x80\x97\xe9\xc4\xe8\xd4\xe9\xc5\x87\x2f\x3f\xff\xfc\x84\xa2\x33\x61\xa5\x2a\xcf\x6b\xa5\x0c\x6b\x74\x6f\x9b\xd8\x7d\x24\x89\x6b\x0f\x7e\x27\x95\xf6\x30\x52\x45\x2e\x3d\x08\xa1\xd6\xe0\x37\x8a\x28\x14\x2a\xa2\x37\x32\xff\xe6\xe9\xc5\xc5\xc5\x18\x31\x3c\xa4\xe6\xc5\xf1\x40\x8e\xc8\x6d\x40\x4f\x61\x20\x08\x50\xf6\x42\x16\x7b\x31\x7d\xfb\x5c\x38\xf1\xaa\xf9\x03\xc8\x9a\x9f\x06\x38\x21\xfb\xd2\xea\xf7\x91\x36\xcf\x19\x9a\xe9\x4f\x34\xcc\x61\xba\x91\x9c\x54\x04\xbf\x73\x0c\x04\x41\x82\x8d\x31\x47\x27\x27\x6e\xb2\x21\x48\xd3\x32\xf2\xec\xe2\xc3\xe7\x17\x17\x67\x7b\x0a\xa2\x47\x73\x7b\x7d\x38\xa8\x0b\xa3\x3a\x11\x23\xf5\xe1\x4c\x38\x79\x85\x6d\x1d\x4d\x8a\xf6\x4c\xe9\x82\x70\x73\x3b\x8f\x35\x79\x68\x58\x4f\x95\x1a\x8c\x64\xb8\xe5\x5b\x5c\x2a\x51\x2f\x25\x24\xa9\x6d\xd1\xcc\x63\xb7\xb5\x71\xa4\xfd\xdb\xaf\x03\x02\xbf\x7d\x44\xc6\xc3\x09\xbd\x2b\xcd\xe5\x6c\x4a\x1e\x9b\x93\x28\xf5\x48\xe0\x07\x51\xba\x6b\x65\x3d\x96\x73\x7f\xdf\x3b\x66\xef\x3f\xd9\xbe\x7f\x72\x45\xec\x05\x10\xc2\x6e\x8c\x58\xfa\x11\x3f\x52\x9d\x3c\x5e\x3c\x37\x69\xf0\x51\xda\xdb\xb9\xbf\xb6\x96\xea\xb5\x12\x8d\xac\xd9\x41\xaa\xd7\x49\x74\xb8\x11\x1b\xa5\xc1\xc7\x68\xef\x4d\x99\xc4\xa9\x06\x7f\x30\xed\x7d\x5c\x13\xba\x67\x2d\x05\xa3\xfa\x0f\xb9\x72\x36\x9b\xdf\x63\x4d\xef\x44\x26\x0f\x72\x02\xf4\x91\x49\xe3\xcc\xef\x87\x33\xbd\x7d\x72\xab\x43\x9f\x57\xbd\xb1\x2f\x23\x25\x53\x96\x6d\x88\x3a\x66\x9d\x2f\x43\xf0\xd1\xf9\xac\x42\x12\x30\x37\x8b\xb6\x33\x11\x59\xed\x34\x63\x0f\x36\x58\x0a\x94\xe2\xe3\x08\x68\x3c\xe0\x51\x75\x50\xe3\xea\xa5\x8e\x60\xea\x28\xaf\xe3\x11\x7c\xd4\x8f\xc5\xeb\x18\x30\x7c\x10\xa7\xe3\xc1\xa4\x20\x8a\xfa\x26\xba\x4c\xa2\x8b\xcf\x75\xb2\x90\x04\x59\x13\x49\xd7\xe5\x02\x65\x55\x83\x50\x77\x72\xdc\x3c\x77\x5a\x1c\x27\x04\x5d\xe0\x40\x73\x47\x13\x40\x39\xbe\xc6\xa0\x36\xbb\xc5\x74\x9e\xc1\xbe\xe1\x7d\x6d\x5c\x96\x76\x3b\x90\xd6\x8c\x74\xf9\xb6\x61\xee\x53\xbf\x56\x31\x52\xdc\x85\x69\xf7\xf7\x34\xc0\xd4\xae\x70\x63\x1c\x6a\x10\xf8\x86\x93\x20\x50\xa4\xe1\x1d\x5f\x89\x29\x5b\x47\x7a\xf3\x4a\x6e\xc9\x50\x0a\xf2\x3b\x34\x47\x03\xd8\xc7\xcd\x53\xc2\x73\x47\xa6\xba\x0c\xa5\x47\xc5\xd5\x24\x0d\xec\x90\x7c\x8d\x52\xf5\xb0\x35\xea\x63\x65\x6c\x42\x81\x1d\x58\x9b\x26\xd2\x3d\x46\xe6\x1e\x61\xd5\x46\xdc\x75\x62\xfd\xc8\xf9\xbb\xdd\xda\x8d\xee\xa7\x5b\x00\x1e\x17\x87\xfd\x66\x31\xf1\xd6\x7c\x3b\xcd\x72\x4f\xb6\x77\xb2\x36\xff\x9a\x55\xcd\xa7\x2e\xbb\xca\x0d\xea\xf7\x65\x17\x81\x46\x7f\xd0\xe1\x58\x3c\x5e\xf1\x88\xf7\xea\x68\xeb\x75\x98\x7b\x1e\xbb\xf7\x93\xcc\x2a\xb6\x95\xba\x18\xb1\xb5\x63\xcc\x7e\x9f\x24\xf9\xe2\x2f\x69\x68\xe0\x10\xd7\x4f\xb9\x6f\x9c\x50\xf6\x70\xd8\x8e\xf8\xc5\xd8\x7c\x74\x12\xd8\xda\x80\xd2\xfd\x64\x48\x0e\x63\x88\xa2\xde\x6e\xdb\x1a\xd8\xb2\xf0\xcc\x3c\x42\xa9\x3d\x32\x51\x74\xb9\xa0\x7b\x0a\x5b\xa5\x72\xac\xa9\x58\x16\xab\x9d\xce\x9c\xa7\x92\x97\x2b\x9a\xef\x0e\xb6\x8a\xfb\xf4\x71\x6d\x62\xb1\xdb\xff\xe2\xf3\x8b\x8b\x1d\x19\x69\xd7\xf8\x8b\xe8\x8e\x55\x95\x14\x8b\x15\x39\xf5\x4f\x73\xc4\xf0\x41\xdd\xe4\x94\x82\x5f\xc9\xbf\x1d\xdc\x6f\xe7\xf5\x39\xfd\xdf\x1a\x49\x58\x27\x05\x18\xc7\xbb\xb5\x24\xac\x93\x02\x0c\x6c\x1c\x96\x84\x9d\xae\x37\x51\xb1\x1c\xde\x41\xbe\x9b\xb4\x05\x37\xe8\x9e\xb2\xb6\x24\x21\x43\xb6\x58\xa8\x27\x17\xb4\x3d\x35\x48\x10\xd4\x8e\x6f\x38\x08\x67\x4b\xb8\x5c\x10\xfe\x8e\x02\xd6\x27\x5c\xad\x0b\xd4\xc7\x73\x7f\xbe\x9b\x80\xf9\x58\xcc\x52\x19\x48\x85\xd8\xf5\x5c\xdd\x05\x64\x09\xb7\x54\x79\x9c\x64\xf1\x88\xa4\xcc\x55\x13\xb5\xb2\x86\xc5\xe7\x04\xcf\x16\xee\xee\x0e\xcb\x26\xf8\xa9\x0c\xe8\xac\xf4\x72\xa4\x2b\x56\x31\x31\x76\x90\xae\xa8\x89\x61\x0c\x69\xb6\x62\x3c\xcf\x31\x77\xb9\x14\xf7\xd1\x33\xe7\x83\x75\x09\x25\x89\x0f\xbe\xf5\x6a\xb7\x2e\x59\xc7\x05\x7b\x9a\x0d\x95\x04\xa7\xa0\x3c\xf8\x3d\x64\x0f\x40\x7c\xf4\x62\x87\xb3\x58\xb7\x4b\xfa\x80\xcc\xae\xc4\x11\x09\xb6\xb3\x98\xda\x6d\xe3\x08\x48\x5b\xce\x30\x1b\xb8\x47\xc4\xbc\x78\xe1\x1b\x1d\xc9\x6a\xc5\x02\x1f\x4d\xba\x5e\x2e\x2b\xb3\x7a\x21\xeb\x09\xbb\x5e\xf0\xda\x0f\xa1\x7d\x82\x9c\x27\xe7\x5a\x25\xe7\xc0\xf8\xcf\xad\xcd\xee\xb6\x52\xa7\xbb\x7b\x07\x48\xcf\x39\x9b\xeb\x82\x58\x8e\xa5\x35\x40\x4a\x76\x26\x68\xf8\x33\x7f\x4b\xe5\xc6\x5e\x40\xa9\xa1\x9e\x21\x93\xa3\x7e\x88\xe7\xaf\x1c\x6f\xcc\xbd\x62\xb3\x46\xaf\x66\xea\x03\x93\x4b\x7e\x23\x62\x24\x2d\x74\x07\x3c\x32\x03\x43\x84\x43\x28\x33\xe0\x01\x2e\xb9\x8c\xa8\x49\x20\xee\xb9\x34\xae\x61\x8a\x15\xbd\x66\x16\xbd\x92\xd7\xaa\xa2\x12\x0e\xc0\x5f\xec\x62\xdc\x82\xc3\x7d\xaf\x64\xa2\x6f\xce\x0d\xef\xa4\x24\x7c\x31\x28\x22\x40\xba\xf7\xb9\xac\x87\x25\x63\x29\x72\xd9\x2c\xdd\xf1\xaf\x65\xce\x7f\xf9\xf9\xe7\x5b\x09\x46\x4b\x28\xfe\xea\xae\xd9\x27\x16\xd2\x84\xc6\xc0\xf3\xff\x3e\xb1\x3a\xa3\x05\x25\xb9\xea\x0b\xe6\xd1\x05\x5d\x94\x33\x7a\x11\x8c\x15\xe2\xac\x2c\xc3\xbd\x1d\x71\xe1\x1e\xf2\x4c\xc3\xdf\x83\x81\x04\x61\x6f\xe9\x5c\xdf\xc3\xf0\xe7\xf5\xbd\xb5\xcc\x6a\x3a\x33\xd0\xed\xe3\xaa\x0a\xc1\x2d\xcb\x6a\xae\xfd\x01\x9d\xae\x02\xd3\x30\x18\x17\x37\xb3\x9f\xad\xe5\x62\x78\xd7\x1b\xf3\x13\xa6\xea\xd0\xcb\x44\x43\xa9\xaa\x27\xec\xfb\x57\x2f\xc6\x2b\xa9\xf1\x12\x88\x6e\x8d\xae\x00\x6e\x11\x0a\xb3\xa5\x3c\x02\xb5\x3f\x3d\x90\xdd\xbf\x51\x1a\x81\xad\x67\x38\xd9\x33\x4b\xcd\x33\x2c\x74\x77\x36\x69\x45\xab\x74\x45\x75\x27\x31\xf5\x45\x12\xfa\x45\x75\x17\x31\x8d\x23\xbf\xfb\x45\x75\x5b\x31\x45\x88\xdb\x1d\x0b\x36\x89\x29\xc0\xf4\xa2\x0a\x0f\xd1\x51\x07\x62\xf6\x8d\xa7\xfb\x31\x84\x78\x40\x8d\x7e\xf9\xe5\xa1\xc4\xf6\xcb\x2f\x1f\x93\x1a\xfd\xf2\xcb\x07\x53\xa3\xf0\x9f\x3f\xd5\xe8\x48\x35\xfa\xe5\x97\x93\x23\xe9\xd1\x2f\xbf\xfc\x48\xf4\xe8\x97\x5f\x3e\x88\x1e\xed\x93\xd3\x3f\xf5\xe8\x6e\x7a\xf4\xab\xaf\xbe\x3a\x90\xd8\x7e\xf5\xd5\x57\x8f\x48\x8f\x7e\xf5\xd5\x57\x0f\xa4\x47\x3f\xe0\x7f\xfe\xd4\xa3\xe3\xf4\xa8\x15\x9b\xa3\xa8\x51\x0b\xf8\xa3\x50\xa3\x56\x54\x4f\xaf\x46\xfb\xc5\xf4\x4f\x35\xfa\x30\xa7\xfa\xee\x89\xfe\x54\x42\x3b\xe2\x44\xff\xe7\xe9\xfb\xa0\xa7\xef\x03\x09\xca\x47\xa1\xdb\xe0\xa8\xbd\xa3\xfc\xb8\x5c\xfb\xc3\xe8\xa1\x83\xe4\x2a\xf5\xc8\x0f\x40\x7c\x3c\x7a\x68\xcf\x63\x71\xf7\x48\xfc\x08\xf4\x90\x3b\x12\xff\x79\x7c\x3d\xe8\xf1\xf5\x40\x82\xf2\x71\xe8\x21\x7b\x54\xdd\x51\x7e\xfe\xd4\x43\xa7\x3f\x56\x76\x8f\x94\x0f\xaf\x87\xc0\x4e\xf7\x0d\x87\xfa\x05\xc9\xbe\xcb\xf5\x9f\xc7\xc0\x5d\x8e\x81\x07\x12\x98\x8f\x42\x1f\x79\x59\xda\x5e\x8e\x50\x1d\x6d\x94\xa5\x3f\xcf\x69\x3d\x7a\x29\x54\x71\x1a\x2f\x69\xf4\xbd\x2a\xa3\xe0\x6a\x18\x21\x6e\x00\x1f\x02\x90\xeb\x5a\x64\x14\x0a\x77\x6a\x07\x58\x2a\x43\xfe\x28\x3f\x5a\x1f\x9d\x62\xe7\x3a\x95\x42\xd9\x8f\xd3\xb8\xa4\x5a\x0c\x76\xcc\x0d\x71\xab\x27\x60\xf0\x78\xfd\xb2\xcf\x4e\x14\x71\xde\x39\x95\xf6\x8d\x34\xec\xea\x06\x4c\xe5\x38\xbe\x0a\x60\xbf\xd6\xbc\xaa\x44\xed\x97\x48\xc8\x2a\x26\x4e\x4f\x58\xa9\x58\xcd\x7b\x1b\xd0\x77\xc5\xe3\x9e\xc0\xb5\xb6\x1e\x3b\xf9\x8c\x37\x5a\x00\x24\xab\x77\x73\x19\x6a\xef\x2e\x44\xc9\x1a\x4d\xe9\x09\x3e\x5d\x38\x2a\xbc\x3d\xaa\x00\xc4\x17\x17\x71\x1f\xc5\x5f\x08\x01\xcb\xc8\x2f\x58\xed\xca\x1a\x53\xab\x20\x17\xba\xaa\xa3\x34\xea\x9e\x38\x9b\x69\xe8\x68\xf0\xfa\x0d\xb5\xae\xb8\xe7\x12\x78\x67\x71\xa5\x41\x3a\x11\x31\x9f\xf5\x14\x72\x45\x52\x05\x8e\xbc\x27\x52\x8d\xe6\xcc\xb5\xc8\x6a\x61\x5c\xf3\xa8\x1e\x26\xb9\xfa\xe3\x7b\x33\xca\xd5\x31\xdf\xd0\xdd\x03\xf1\x89\xb2\x3a\xda\x68\x75\x2a\xbb\x42\xf8\x50\xdc\x25\x02\x03\x90\x28\x6c\x4e\x1b\x5e\x63\xbb\xfc\xb5\x73\x5d\xe3\xf4\x3d\x28\x23\xae\x6a\xf5\x2f\xac\x26\xd0\x29\x40\x51\xe1\xa3\x4d\xd1\xb9\x01\x42\xa6\x96\x33\x59\x8a\x3c\x4a\x1b\xb1\x4f\xa0\xce\x42\xa6\x96\x95\x2a\xc1\x0c\xc1\x4a\x25\xfc\x16\xe9\xd2\x54\x18\xe4\xe5\x07\x83\x48\xcb\xdf\xae\xfc\xdf\xbf\xef\x1e\x45\x99\x36\xba\xaa\x3c\xa2\x2e\x8e\x93\x9a\xea\x42\x2b\x0a\xcb\x0a\x3d\xa1\x85\xe9\xba\xe9\x42\xb1\xd8\x28\x7a\x14\x20\x85\xc6\x6a\x59\xd5\x0c\x34\x8a\x6c\x3d\xf1\x5d\x38\x7d\x8a\x49\x3b\x7e\x17\x2a\x2b\x18\xec\x67\xde\xc2\xc4\xf5\xf4\xf5\xf6\x5c\x02\x3b\xa4\x0f\x43\x81\x99\x7b\x51\x14\xf6\x7f\x07\x10\xe8\x06\x44\xf6\x87\x8f\x8e\x57\xbe\x9e\xaa\xef\x1d\xfb\x37\x8b\x58\xa7\x86\xcd\x96\xd5\x79\x63\x91\xdb\xa6\x4e\x2f\xee\x64\xc3\x55\x33\xb6\x6e\x68\x62\x16\xb5\x48\xc2\x1a\xe1\xd7\x48\x41\x5b\xf4\x8b\x15\x94\xe7\x86\x79\x92\xc8\xb7\xe6\x1a\x67\xa9\x5d\xfa\x86\xc7\xe1\x8a\xa7\x44\xad\xe1\xca\x72\x58\xf5\x05\xdb\xba\x9f\xfd\x46\xb8\xc1\xf8\x6f\x2d\x8a\xcb\x56\x7f\x6e\x6b\x4f\xc0\xbf\xce\x9f\x9e\xa1\xb4\xfa\x59\x07\x5a\xbb\x56\x2c\xf8\xc4\x0f\x32\xf1\xd1\xc4\x83\xd2\x9d\x2e\x2f\x2f\x8c\x6d\x48\x49\x14\x7a\x67\x5c\x9a\x67\x34\xae\x1b\xb3\x1d\xa3\xec\xc7\x75\x95\x43\x5a\x8b\x6a\xca\x5e\x20\xa1\x7a\xc7\xf1\x82\x98\xa4\x11\xfa\xf9\xb9\x16\xd5\xdd\xc9\x85\x89\x75\xf8\xbb\xd3\xba\x1a\x68\x3b\xbc\x76\x61\x6d\x69\xfa\xf6\x2d\xa9\xb1\xa5\xae\xf6\x8c\x75\x8f\x05\x72\x48\x47\x9f\x85\xaa\xe4\xb8\x89\x2a\xea\xef\x18\x8b\x65\xdc\xb8\x2d\xb2\x33\x81\x06\xd3\x8d\x72\x69\xcf\xc8\x68\x90\xce\x5b\x95\x67\x74\x03\xa1\xee\xf3\xa6\xb0\x4b\x99\xb4\xb0\x4b\x6d\x6a\x9f\xb6\x66\xf1\x1d\xc6\xe9\xd8\x3d\xfa\xbe\x7c\x6f\x46\xef\x53\xc5\xec\x08\x4c\x8f\xd1\x49\xea\x8c\x31\xac\x33\xf6\xc7\x66\xfb\x36\x79\xa1\x7b\x73\x3e\x5e\x5f\x07\x29\xd1\x7b\x2c\x1d\xd0\x5a\xfb\xde\xc7\xf6\xf9\xa9\x05\x22\x4e\x10\xa4\x36\x1b\x87\xca\xdb\x03\x81\xc2\x5c\xd4\x5d\x7c\x29\xfb\x0a\x9e\xef\x25\x71\x64\x71\xdb\xb9\x12\xee\xc9\xf7\x97\x77\xed\x6a\x65\xbc\xd0\x2a\xa9\x9b\x18\x55\x80\xae\xb8\x59\x8c\x13\xc5\xae\x18\x06\xab\x09\x0b\xa8\x41\x15\x01\xe7\x66\xf8\x18\x94\x16\xd2\xe4\x21\x94\xd7\x91\xca\xda\x3e\x88\x1e\xdb\x20\x6f\x0e\x62\x28\xb2\xb7\xaf\xbc\xa1\x21\x9c\xca\xdc\x4e\x3a\x91\xe4\xed\x0f\xaa\x13\x4f\x69\x8b\xb5\x84\xfa\xe3\xb2\xcc\x36\x2a\xcc\x58\xe0\x0e\xa8\x30\xd1\x63\x72\x00\x01\x3e\x9d\x60\xb5\x6a\xc2\x42\xc9\xd3\x83\x08\x56\x4f\x79\x58\xe7\x24\x31\xae\xe3\xe2\x2e\xe5\x61\xb7\xf5\xc1\x8d\x11\x28\x9f\x9c\x1c\x24\x26\x08\x8b\xb9\x57\x51\xfb\x41\xbf\xb3\x40\x29\xd7\xcd\xee\x81\x96\xe8\x64\xfd\x26\x9f\x97\x23\x3b\x58\xb4\x0a\xb7\xad\x18\xbb\xaf\x38\x6c\xae\x1f\xdb\xc7\xff\xe3\xf5\xaf\x3a\x86\xee\x28\x73\xab\xc3\xed\x98\xda\x7b\xcf\xa2\x86\xf3\xf6\xcb\x52\xdc\x3b\x2f\x4e\x8f\x5e\x40\xe5\x81\xdf\xa5\x3c\x05\xec\xc8\xc7\xd5\xaf\x52\x9a\xe0\x7c\x42\xaf\x58\x54\x31\xd9\xc2\xb9\x91\x50\x32\x57\x11\x94\x67\x47\x66\x7d\xe4\xa2\x1d\x5b\x34\x36\x00\x89\xdd\xd7\xa7\x28\x1b\x3b\xde\xe7\xde\x76\xac\xe3\xc6\xbd\x87\x73\xbd\xc3\x4b\x17\xa7\x15\xd6\xb9\x9b\xe4\x51\x1d\xe1\x51\xcd\x80\x1d\x98\x3b\xa2\x14\xe5\x6e\xdc\x3d\x4c\x09\xd9\x47\xcf\xdf\x4e\x11\xca\xc7\xc4\xe0\xd1\xb5\x64\xb7\x67\xf1\x01\xab\xc9\x3e\x6a\x1e\x0f\x14\x93\x7d\x84\x5c\x3e\xca\x4a\x3e\x68\x59\xd9\x8f\x81\xd1\x8f\x7a\x3d\x47\xc5\x65\xb7\x29\xec\x39\x8a\xed\x0f\x5f\x56\xf6\x21\xc5\x03\x8f\x87\x57\x3f\xb7\xaf\xba\x43\xdf\xe2\x39\xb4\xf0\xa4\x7b\x6d\xfb\x96\x03\x5b\x0b\x08\x64\x59\x57\x98\x76\xf3\x91\xa0\x43\xdf\xc7\xad\x6b\x4e\x27\x84\x0f\x53\x5f\xf6\x4f\x51\x34\x1f\xc3\xce\x37\xa6\xd0\xec\x28\xb9\x3b\x60\xa9\xd9\x47\xbd\xc9\x55\x9d\x3a\x90\x8f\x89\x9d\xbb\x79\xe8\x7b\xd8\x7a\x82\xc2\xb3\x0f\xc9\xe6\x77\xf1\x2a\x75\x91\xd6\x6e\xa9\xc7\xce\x28\x8b\xe9\xf8\xdb\xc8\x44\x38\x50\x74\x36\x0a\x48\xa8\x3c\x1d\xf1\x6e\xd9\x68\xf3\xf1\xdc\x48\x3e\x12\x79\x3d\x66\xf1\xda\x3f\x85\xf5\x4f\x61\xed\xd4\xae\xdd\x59\x5a\x8f\x5e\x05\xf7\xe1\xc4\x15\x7e\x8b\x0a\xc8\x42\x05\xd3\x11\x61\xb4\xbd\x45\x70\x37\x6f\xad\x8c\x3d\x8f\x3e\xa4\xe2\x94\xa5\x0b\x1f\xdc\xb0\x02\x5c\x90\x21\xc5\xeb\xce\x55\xed\x97\x41\x04\xf5\x41\x84\x0c\x8b\xab\xee\x2b\x60\x47\x29\x75\xfb\xc0\xb2\x85\xd5\x63\x51\xac\x7c\xc5\xf8\x41\x16\xb7\x2b\xdd\x6e\x90\x28\xf6\xa3\xa3\x3b\xdb\x5f\x98\xe0\x67\x04\x78\x74\x19\xba\xf6\x51\xe8\x69\x7c\xf6\x36\xb1\xd9\x18\xc9\x3e\x2a\x30\x9b\xc9\x32\x4e\x5c\x3a\x56\x60\x36\xc5\xd6\x77\xa2\xb2\xc3\x8d\x1a\xdb\x27\x2a\x1b\x83\xb2\x39\x0d\xb3\x11\xea\x60\x4c\x36\x11\x8e\xee\xb6\xfc\xe4\xe8\x67\x19\x55\xdf\xdd\x3e\x00\x9b\x80\xb4\x22\xaf\xdb\x31\xce\x51\xf4\xb5\x1f\x75\x43\xe8\x75\x7b\x34\x8f\xa4\x13\xe4\x74\x56\x51\xdc\x75\x3a\x42\x97\xf6\xc9\xf9\xb8\x13\x74\xdd\x9e\xd0\x21\x22\xae\x11\xe6\x16\xab\x64\xe7\x60\x6b\xc2\xfe\x01\x22\xad\xd7\xdc\xc5\x23\x52\xe1\x76\x96\x22\x31\x08\x57\x27\xa4\xde\xa5\x71\x2b\x56\xdb\x87\x5e\x93\x03\xa5\xff\xfe\xdd\x42\x1c\x8e\xcb\xe8\x86\xae\xb1\xd9\xca\x0d\x7e\x70\x76\x77\x99\xed\x0b\x8a\xb9\xd8\x94\xb9\xfe\xbe\x56\x4d\x75\x3c\x8e\xc7\x91\x34\x9d\x20\x5c\xe8\xe6\x8d\x18\x1c\x29\x90\xed\xa0\xa2\x92\x14\xdd\x58\x70\x3d\x1c\xe4\xf6\xf9\xc5\x84\xcd\xf5\x0d\x91\xd6\x17\x21\x7b\x7a\x71\xf1\x14\x23\x01\xb4\xa8\xdd\x8f\x21\xd0\x48\xe6\x56\x8a\x36\xc7\x7e\x7b\x95\xb7\x83\xdc\x9d\xd3\xd1\x24\x4d\x8f\xc6\x58\x90\xa3\x25\xc9\xee\x57\x8c\xe1\x40\xca\x6d\xfc\xa1\x7a\x17\x39\x3f\x51\x80\xf9\x11\x54\xdf\x90\x10\x7f\xf8\xfc\xe2\xc2\x05\x92\x41\xd3\x82\x8d\x16\xe6\x2e\x22\x09\x10\xdb\xc7\xe5\x7d\x8f\xca\x38\xf1\xfd\xb3\xf6\xf7\x90\xbc\x6d\x82\xcc\x77\x96\xb7\x03\x47\x98\x9f\x72\x5f\x7d\x17\x59\x4f\x49\xf8\xa4\x73\x33\xef\x11\xff\xdb\x16\x3c\x6f\xc6\xf6\xea\x43\xfc\x3f\xd7\xe8\x23\xee\xa7\x7e\x42\x41\x39\xb9\xaa\xea\x86\x93\xff\x31\xb4\x96\x8f\x2f\x4f\x85\x8b\x36\xb8\x90\xd0\xe0\xb5\x03\x76\x58\x3b\xb6\x78\xb1\x5e\xf9\x3a\x41\x11\x9b\x93\xca\x70\xc8\xbf\x1f\x1f\xe5\xbb\x4e\x82\xd7\x84\xf8\xf2\xd3\xc4\xf6\xee\x6a\x24\x06\xe9\x1b\x17\xe7\xbb\xd9\x2b\xb8\x69\x73\x5d\x1f\xe1\xbb\x93\x7c\x1e\x50\x78\x48\x54\xbc\xe8\xec\x94\x3b\xef\x80\x8c\x74\xcb\xec\x73\xf0\xdc\xd6\x2d\x93\x88\x8d\xf3\xd2\xb8\xd0\xe0\xa1\xb9\x6e\x9f\x3b\x0f\x10\xc1\x55\x93\x3a\x6a\xf6\x70\xd2\xa4\x89\xf2\xa9\x43\x63\x67\x27\xcd\x16\x29\xf2\x63\x9d\x34\x1b\xf3\xe3\x77\x75\xd2\xa4\x4b\xef\x88\x4e\x1a\x92\x95\x81\x5e\x5c\xed\x15\xd2\xe3\x97\x99\x24\x7a\x07\x12\x1c\xe0\xd6\x4a\x96\x41\xaf\xc0\x6c\xec\xaf\xba\xda\x50\x12\xc8\x0d\x18\x16\x8f\x23\x2d\xdd\xa0\x59\x25\x4b\x58\xd4\xe2\x86\xd7\x79\xe1\x1a\xcd\xaa\x39\xe3\x91\x2a\x23\xac\xc4\x07\xa9\x61\x33\x5a\x83\x5e\x40\x6d\xa7\xc8\x88\xb6\x9c\x76\x47\xb2\xda\xcf\x8f\xa1\xa7\xdd\x85\x1c\xeb\xef\x54\xd9\x47\x9d\xeb\x7a\x2a\xd7\x6c\x3e\x91\x3b\x5d\x30\xd0\xb8\x2d\x5a\x0f\x9d\x26\x75\x76\xf9\x42\xb8\x88\x83\x71\xbf\x90\xd9\xc2\xfb\xde\xb9\xd6\x2a\x93\x61\x09\x07\x22\x62\x11\xf5\x2a\xd9\xd4\x70\x07\x0a\x3d\x3f\x69\xc7\x88\x56\xe6\x56\x6e\xa8\xa7\xcf\x0e\x24\xd1\x23\xbc\x8b\x5d\x99\x5c\x6f\xcf\x1e\x42\x88\x7a\x64\x64\x93\x7c\x90\x11\xb2\x9d\x8c\x74\x34\x49\x2a\x1e\x2d\x95\xd9\x2b\x22\x66\x98\xaf\x3d\x3c\x45\x8d\xb9\x83\x7b\x71\x77\x45\xe5\x3c\x5f\xe8\xd2\x0b\xee\x2e\x4a\x9c\x3b\x28\xeb\x23\xcf\x62\xbf\x07\xe6\x90\xde\xc5\xa3\xc9\x0c\x7e\xdb\x69\xd0\x7b\xf1\xe1\xf3\xcf\x2f\x7a\xfa\x20\xa4\x89\x88\xfe\xe4\xe1\xa6\x89\xbf\x0f\xa4\x06\x9d\x5c\x10\x9d\xaf\x71\x86\x96\x90\x93\xc3\x13\xb8\x78\x0e\x50\x02\x76\x9f\x45\x70\x60\x49\x6f\x4b\xb6\x77\x29\x7f\x64\x12\xbd\x31\x0e\xa7\xcf\x78\xdc\x6e\x13\x5d\x23\x98\xad\x9d\xcf\x9f\x7c\x22\x0d\xb9\xb5\x64\xa2\xb5\x75\x9c\xf3\xf8\x76\x02\x48\xfe\x9c\xc3\xcb\x9d\x73\x14\xed\x77\x8c\x3a\x8e\x90\x6d\xe3\x23\x8c\x94\x5e\x27\xc2\xab\x2d\x5b\xe1\x40\x9f\xc0\x3f\xa8\x59\x75\x60\xc6\x9f\x42\x05\x25\xa2\x70\x58\xbf\xe1\x29\x05\x05\x77\xcc\xcd\xfa\x09\xa7\xb9\xdd\xe6\xb9\x49\x86\x00\xe6\x1a\x39\x1a\x2c\x36\xf1\x58\xbc\x84\x3b\x09\xe7\xf6\x55\x00\xd6\x0a\x68\x8f\x5b\xd0\xbb\x04\x8f\xa5\xa6\xec\xb9\xb2\x4f\x02\xf5\x08\x11\x94\x65\xd7\xfd\x17\x09\x45\x4f\xac\x7d\x27\x12\xa5\x2d\x75\x33\x85\xf5\x71\x5b\xe2\xa7\x53\x37\x60\xaf\x0c\x1e\x8c\xd9\x67\xd7\xcd\xec\x8a\x9b\xc5\xd7\xec\xad\xe0\xd0\xf6\xdc\xf9\x28\x01\x09\x1e\x2a\x05\x3b\x7f\xf7\xd9\x5a\x96\x37\x33\x58\x9d\xcf\x8d\x5a\xca\x8c\xdd\xd7\xd2\x74\xcb\xdf\x7a\x89\xc6\x97\x75\x38\xd2\x87\xc1\xc0\x31\x1c\xeb\xa2\xf5\xbc\x0f\xee\x32\xef\x56\xce\x78\x89\x0b\x7e\x70\x42\x3d\x26\x33\x1c\xd9\xd9\x3d\xef\xb6\xc0\xe7\x0e\xdd\xad\x0c\x0c\x9c\x15\x04\x83\x7a\x8f\x4c\x2e\xef\x64\xde\xf0\x82\x32\x10\x64\x19\xa1\x3f\xe6\xdc\xee\x6a\xeb\x3a\x7c\x3e\x22\x8e\xe2\x0e\x64\xe9\x70\x05\x8d\xf9\xe7\xc1\xdf\xd4\x0e\x70\x7f\x44\x1c\xc7\x18\xe0\x42\x2b\xd6\x68\x38\x8b\x20\x1c\x78\x04\xc5\x84\xa5\x8e\x2e\xa3\xd0\xf2\x95\xdb\xb6\xc9\x58\x2b\x24\xee\xc2\xe4\xb4\x82\x12\xc7\xbb\x9e\x40\x54\xdc\x70\x47\x5c\xfb\xf1\x8c\xfe\x43\x57\x7f\xfb\x96\xec\xa8\x2c\x0d\x83\x1d\x8f\xa7\x61\x8c\xff\x50\x8e\x26\x16\xcd\x51\xd9\x49\x23\x1d\x8f\x97\x34\x40\xcb\x1c\x0f\x7e\xf4\xc3\x31\x92\x98\x18\x6e\x57\x8f\xc3\xc8\xbf\xfc\x7f\x01\x00\x00\xff\xff\x97\x8f\xf3\x10\xa5\x9f\x02\x00") func testConformanceTestdataConformanceYamlBytes() ([]byte, error) { return bindataRead( @@ -1665,7 +1665,7 @@ func testE2eTestingManifestsSampleDevicePluginYaml() (*asset, error) { return a, nil } -var _testE2eTestingManifestsSchedulingNvidiaDriverInstallerYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x54\x4d\x6f\xe3\x36\x10\xbd\xeb\x57\x0c\xb2\x67\x59\x4e\x8a\xa2\x85\x6e\x46\x1c\xb4\x46\xb3\x76\x10\x3b\xb9\x1a\x34\x39\x96\x08\x53\xa4\x3a\x1c\x6a\xe3\x7f\x5f\x50\x72\x1c\xc9\x1b\x27\x4e\x57\x37\xcd\xc7\x9b\x0f\xbe\x37\xdf\x60\x55\x6a\x0f\x53\x81\x95\xb3\x4b\x64\xf8\x21\x3c\x38\xd2\x85\xb6\xc2\x98\x3d\x10\x6e\x91\xd0\x4a\x54\xb0\x25\x57\x25\xdf\xa0\x64\xae\x7d\x9e\x65\x85\xe6\x32\x6c\x46\xd2\x55\xd9\x5f\xce\x15\x06\x6f\x8d\x0b\xea\xc1\x08\xde\x3a\xaa\x32\xe9\x2c\x0b\x6d\x91\x52\xb4\x85\xb6\x98\x0a\x29\xd1\x20\x09\x76\xe4\xb3\x8d\x71\x9b\xac\x12\x9e\x91\x32\xd5\xd6\xf6\xc8\xa3\xbd\xa8\x4c\x92\xc4\x96\x10\xa6\x4e\xee\x90\xb6\xda\x20\x08\xab\xc0\x71\x89\x04\xde\x05\x92\x08\x5b\x47\xc0\xb1\xed\x63\x2a\x08\x42\xd0\xf6\x2b\xed\xf9\xb4\xa8\x43\xaa\xad\x67\x61\x0c\x52\x92\x88\x5a\x3f\x23\x79\xed\x6c\x0e\xa2\xae\x7d\xd6\x5c\x27\x3b\x6d\x55\xfe\xb6\x9d\xa4\x42\x16\x4a\xb0\xc8\x13\x00\x2b\x2a\xcc\xc1\x36\x5a\x69\x91\x2a\xd2\x0d\x52\x0f\xae\xf3\xfb\x5a\x48\xcc\x61\x17\x36\x98\xfa\xbd\x67\xac\x12\x00\x23\x36\x68\x7c\x84\x00\xd8\xfd\xe9\x53\x51\xd7\xe7\x71\x7c\x8d\x32\x86\x7a\x34\x28\xd9\x51\x97\x56\x09\x96\xe5\x7d\x0f\xe7\x02\x24\x80\x50\x2b\xc1\xb8\x64\x12\x8c\xc5\xbe\x4b\xe4\x7d\x8d\x39\x3c\x3a\x63\xb4\x2d\x9e\xda\x80\x04\x80\xb1\xaa\x8d\x60\x3c\x54\xeb\x4d\x1d\x3f\x33\x28\xfc\xf9\x26\x2e\x6e\x10\xe0\x75\xdc\xf8\x89\xed\x56\x5b\xcd\xfb\x5e\x21\xa7\x70\xf2\x93\x15\x80\xf0\xdf\xa0\x09\xd5\x34\x90\xb6\xc5\x52\x96\xa8\x42\x9c\x67\x56\x58\x77\x34\xdf\xbd\xa0\x0c\x1c\x9f\xb7\x97\xd9\x61\x2e\x0f\xcb\x5d\x21\x55\x7e\xe8\x4e\xbb\x5d\xdf\xbd\xd4\x84\x3e\x92\xe3\xc4\x1f\x23\x76\xb8\xcf\x41\x46\x7e\x8d\x8a\x96\x6b\x2d\xed\x8a\xdd\x80\xf4\x27\x59\x00\xae\xee\x1c\x39\xdc\xbd\x68\xcf\xfe\x10\xc0\xae\x4d\xe8\x57\x4a\x7b\xb1\x57\x5d\xf0\xd5\xc1\x55\x3a\xcf\x73\xe4\x1f\x8e\x76\x39\x30\x05\xec\xd9\x1f\x66\xd3\x81\xad\x71\x26\x54\xd8\x43\xed\xde\x4d\x61\x73\xec\xad\x4d\x13\x5c\xf6\x67\xac\xe3\x3f\x64\x6f\x61\xaf\x89\x4d\x30\x3b\x61\x53\x2d\x55\x5a\xb9\x60\xf9\x12\x94\xd2\x55\x98\x45\x39\x90\x45\x46\x9f\x6d\xb4\xcd\x3a\x3e\x64\x1d\x5c\xa6\xa5\x1a\xa9\x93\x4a\x07\xc6\x1c\xa8\x92\x2a\x4d\x69\xac\xf1\x6b\x05\x4f\x6a\x90\x73\x7c\xf9\x1c\x07\x4b\x64\xe2\xed\xeb\xa5\xeb\x6d\x56\x57\xa2\xc0\x1c\x0a\x49\x23\xed\xda\x63\xd3\xd2\xe3\xe7\xb3\x93\x37\x37\xe3\x9b\xf1\xf8\x8f\xf1\xf5\x17\xd5\x44\xd8\x1d\x43\x7f\xaa\x03\xf4\x7c\x42\x51\x59\x87\x1c\xc6\xa3\xeb\xdf\x8f\x56\x8f\x32\x90\xe6\x7d\x6c\x1d\x5f\x78\x30\x1f\xe9\x46\x1b\x2c\x50\x0d\xb8\x03\x80\xb6\xe9\xc7\xbd\xae\x6d\xfe\x3c\x9b\xce\x26\xeb\xd9\x7c\xb9\x9a\xdc\xdf\xaf\xa7\xb3\xc7\xf5\xdf\x8b\xe5\x6a\xd0\x40\x23\x4c\xc0\x4b\xde\xe2\x13\xe0\xdb\xc5\x7c\x35\x99\xcd\xef\x1e\xdf\x45\x0f\x9e\x32\xe3\xa4\x30\xe7\x31\x9f\x9f\xee\xff\x99\xcc\xd7\xb3\xdb\xe9\xff\x6d\xf4\x3d\x96\x7e\x50\xe1\xe3\x8e\x91\xe5\x67\x78\x8f\x8b\xc5\x6a\xfd\x7d\xf1\x34\x5f\x45\xbc\x77\x51\x22\x71\x8f\x8e\x4e\xe3\xdf\x23\x8d\x7b\x2c\xb8\x54\x47\x00\xad\x00\x1e\x3a\x8e\x9f\x5d\xe8\xa7\x07\x60\x88\x73\x76\xcc\xf7\x2e\xd0\x30\xb5\xef\xf9\x40\xa8\xc3\xa4\xde\x42\xe4\x79\x6d\x5e\x1d\xc4\xd9\x5d\xec\xf4\x2d\x32\xab\x45\xf0\x98\xff\x36\xba\xb9\x3a\xd1\x64\xeb\xf8\x2f\x00\x00\xff\xff\xb9\xb1\x2b\x31\x32\x09\x00\x00") +var _testE2eTestingManifestsSchedulingNvidiaDriverInstallerYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x54\x4d\x6f\xe3\x36\x10\xbd\xeb\x57\x0c\xb2\x67\x59\x49\x8a\xa2\x0b\xdd\x8c\x38\x68\x8d\x66\xed\x20\x76\x72\x35\x68\x72\x2c\x11\xa2\x48\x75\x38\xd4\xc6\xff\xbe\xa0\xe4\x78\x25\x6f\x9c\x78\x5b\xdd\x34\x1f\x6f\x3e\xf8\xde\x7c\x81\x75\xa9\x3d\xcc\x04\xd6\xce\xae\x90\xe1\xbb\xf0\xe0\x48\x17\xda\x0a\x63\xf6\x40\xb8\x43\x42\x2b\x51\xc1\x8e\x5c\x9d\x7c\x81\x92\xb9\xf1\x79\x96\x15\x9a\xcb\xb0\x9d\x48\x57\x67\x7f\x3a\x57\x18\xbc\x33\x2e\xa8\x47\x23\x78\xe7\xa8\xce\xa4\xb3\x2c\xb4\x45\x4a\xd1\x16\xda\x62\x2a\xa4\x44\x83\x24\xd8\x91\xcf\xb6\xc6\x6d\xb3\x5a\x78\x46\xca\x54\x57\xdb\x23\x4f\xf6\xa2\x36\x49\x12\x5b\x42\x98\x39\x59\x21\xed\xb4\x41\x10\x56\x81\xe3\x12\x09\xbc\x0b\x24\x11\x76\x8e\x80\x63\xdb\xc7\x54\x10\x84\xa0\xed\xaf\xb4\xe7\xd3\xa2\x09\xa9\xb6\x9e\x85\x31\x48\x49\x22\x1a\xfd\x82\xe4\xb5\xb3\x39\x88\xa6\xf1\x59\x7b\x93\x54\xda\xaa\xfc\xc7\x76\x92\x1a\x59\x28\xc1\x22\x4f\x00\xac\xa8\x31\x07\xdb\x6a\xa5\x45\xaa\x48\xb7\x48\x03\xb8\xde\xef\x1b\x21\x31\x87\x2a\x6c\x31\xf5\x7b\xcf\x58\x27\x00\x46\x6c\xd1\xf8\x08\x01\x50\x7d\xf5\xa9\x68\x9a\xf3\x38\xbe\x41\x19\x43\x3d\x1a\x94\xec\xa8\x4f\xab\x05\xcb\xf2\x61\x80\x73\x01\x12\x40\x68\x94\x60\x5c\x31\x09\xc6\x62\xdf\x27\xf2\xbe\xc1\x1c\x9e\x9c\x31\xda\x16\xcf\x5d\x40\x02\xc0\x58\x37\x46\x30\x1e\xaa\x0d\xa6\x8e\x9f\x19\x15\xfe\x7c\x13\x17\x37\x08\xf0\x36\x6e\xfc\xc4\x6e\xa7\xad\xe6\xfd\xa0\x90\x53\x38\xfd\xc9\x0a\x40\xf8\x4f\xd0\x84\x6a\x16\x48\xdb\x62\x25\x4b\x54\x21\xce\x33\x2f\xac\x3b\x9a\xef\x5f\x51\x06\x8e\xcf\x3b\xc8\xec\x31\x57\x87\xe5\xae\x91\x6a\x3f\x76\xa7\xfd\xae\xef\x5f\x1b\x42\x1f\xc9\x71\xe2\x8f\x11\x15\xee\x73\x90\x91\x5f\x93\xa2\xe3\x5a\x47\xbb\xa2\x1a\x91\xfe\x24\x0b\xc0\x35\xbd\x23\x87\xfb\x57\xed\xd9\x1f\x02\xd8\x75\x09\xc3\x4a\xe9\x20\xf6\xaa\x0f\xbe\x3a\xb8\x4a\xe7\x79\x81\xfc\xdd\x51\x95\x03\x53\xc0\x81\xfd\x71\x3e\x1b\xd9\x5a\x67\x42\x8d\x03\xd4\xfe\xdd\x14\xb6\xc7\xde\xba\x34\xc1\xe5\x70\xc6\x26\xfe\x43\xf6\x23\xec\x2d\xb1\x0d\xa6\x12\x36\xd5\x52\xa5\xb5\x0b\x96\x2f\x41\x29\x5d\x8d\x59\x94\x03\x59\x64\xf4\xd9\x56\xdb\xac\xe7\x43\xd6\xc3\x65\x5a\xaa\x89\x3a\xa9\x74\x60\xcc\x81\x2a\xa9\xd2\x94\xc6\x1a\xff\xaf\xe0\x49\x0d\x72\x8e\x2f\x9f\xe3\x60\x89\x4c\xbc\x7b\xbb\x74\x83\xcd\xea\x5a\x14\x98\x43\x21\x69\xa2\x5d\x77\x6c\x3a\x7a\xfc\x7c\x76\xf2\xf6\xf6\xfa\xf6\xfa\xfa\x8f\xeb\x9b\x5f\x54\x13\x61\x7f\x0c\xfd\xa9\x0e\xd0\xf3\x09\x45\x65\x13\x72\xb8\x9e\xdc\xfc\x7e\xb4\x7a\x94\x81\x34\xef\x63\xeb\xf8\xca\xa3\xf9\x48\xb7\xda\x60\x81\x6a\xc4\x1d\x00\xb4\xed\x30\xee\x6d\x6d\x8b\x97\xf9\x6c\x3e\xdd\xcc\x17\xab\xf5\xf4\xe1\x61\x33\x9b\x3f\x6d\xfe\x5a\xae\xd6\xa3\x06\x5a\x61\x02\x5e\xf2\x16\x9f\x00\xdf\x2d\x17\xeb\xe9\x7c\x71\xff\xf4\x2e\x7a\xf0\x94\x19\x27\x85\x39\x8f\xf9\xf2\xfc\xf0\xf7\x74\xb1\x99\xdf\xcd\xfe\x6b\xa3\xef\xb1\xf4\x83\x0a\x1f\x77\x8c\x2c\x3f\xc3\x7b\x5a\x2e\xd7\x9b\x6f\xcb\xe7\xc5\x3a\xe2\xbd\x8b\x12\x89\x7b\x74\xf4\x1a\xff\x16\x69\x3c\x60\xc1\xa5\x3a\x02\xe8\x04\xf0\xd8\x73\xfc\xec\x42\x3f\x3d\x00\x63\x9c\xb3\x63\xbe\x77\x81\xc6\xa9\x43\xcf\x07\x42\x1d\x27\x0d\x16\x22\xcf\x6b\xf3\xaa\xfa\xea\x27\x07\x81\x36\x22\x78\xcc\x7f\x9b\xdc\x5e\x9d\xa8\xb0\x73\xfc\x1b\x00\x00\xff\xff\x7e\x84\x27\x2d\x24\x09\x00\x00") func testE2eTestingManifestsSchedulingNvidiaDriverInstallerYamlBytes() ([]byte, error) { return bindataRead( @@ -2365,7 +2365,7 @@ func testE2eTestingManifestsStorageCsiExternalSnapshotterRbacYaml() (*asset, err return a, nil } -var _testE2eTestingManifestsStorageCsiGcePdController_ssYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x55\x51\x6f\xe3\x36\x0c\x7e\xcf\xaf\x20\xb2\x67\x3b\xcd\xb0\xc3\x06\x03\x79\x08\x7a\x41\x56\x5c\x2f\x0d\xae\xc5\xf6\x78\x60\x65\xc6\xd1\x22\x4b\x1a\x49\xbb\xcd\x86\xfd\xf7\x41\xb5\xd3\x25\x69\xba\xad\x38\xa4\x7a\x32\x28\x7e\x1f\xc9\x8f\xb4\xb8\xb1\xbe\x2c\xe0\x56\x51\x69\xd5\xb8\x5b\xd2\x01\x46\xfb\x0b\xb1\xd8\xe0\x0b\xc0\x18\x65\xd4\x8e\x07\x35\x29\x96\xa8\x58\x0c\x00\x3c\xd6\x54\x80\x11\x9b\x55\x86\xb2\x58\x66\x26\x78\xe5\xe0\x1c\xf1\x40\x22\x99\xe4\x23\xc4\xad\x35\xb4\x78\x72\x1d\xfe\xe3\x3b\x1c\x00\x30\x45\x67\x0d\x4a\x01\xe3\x27\x4f\x47\x46\x03\x27\x14\x40\x8d\x6a\xd6\xd7\x78\x4f\x4e\x3a\x03\xa4\x14\x0a\xa8\x4c\xcc\x4c\xa8\x63\xa3\x94\xc5\x94\x9c\x28\x79\xcd\x4a\x2b\x9b\x2c\xb1\x97\x6c\x5b\xe2\x01\x80\x52\x1d\x1d\x2a\xf5\x74\x7b\x69\xa7\xe3\x0e\x98\xdf\xca\x0d\xb0\x2b\x2f\x9d\xef\xe0\xe7\x20\x0a\x9e\xf4\x21\xf0\x06\xea\x46\x14\xee\x09\x1a\xa1\x12\x56\x81\xc1\x7a\x25\x46\xa3\x36\x78\x78\xb0\xba\x86\x5f\x03\x6f\x5c\xc0\x12\xae\x4a\xf2\x6a\x75\x0b\xd6\xc3\xfc\xd3\xec\x99\x4f\xac\x37\x04\x56\x9f\x14\x42\x43\x02\xf3\xcb\x19\x7c\xee\x6b\x80\x5b\xe2\x96\xb8\xe3\x9a\x7f\x7a\x71\x91\xc3\x17\xaa\x43\x4b\xcf\x74\xba\xb6\x02\x4c\xbf\x37\x96\xa9\x26\xaf\xf0\xb0\x26\x0f\x56\xa4\x21\x78\xba\x91\xe0\x5a\x2a\x01\x7d\x09\xf7\xb4\x0a\x4c\x80\x7e\x0b\xf4\x18\x83\x34\x4c\x10\x56\xcf\x54\x35\x29\x5b\x23\x10\x03\xab\xf4\xd6\x75\x10\x5d\x74\xc5\x17\xa0\xdc\xec\x02\xf7\xad\x9f\x1a\x13\x1a\xaf\x8b\xd7\x87\x25\x13\xec\x21\xc9\x86\xd6\x13\xef\xb5\x26\xdb\x9b\x33\xf1\x18\x65\x1d\x54\xfb\x36\x74\xc7\xd6\x58\x51\x6a\x1f\xe7\x36\x8c\x36\x3f\x49\x26\x8a\x95\xf5\x55\xea\xda\xe8\x08\x57\xb4\xdf\xe7\x17\xf9\x78\x0f\x8e\x5c\xed\x85\xeb\x42\x0e\xb3\xac\x9d\x7c\x18\xbe\xb4\x26\x36\x2c\x4b\x26\x91\xc9\xa8\xa7\xcf\x25\x98\xcd\xf0\x38\xa1\x65\xe3\xdc\x32\x38\x6b\xb6\x05\x4c\xdd\x03\x6e\x65\xcf\xa3\x0d\xae\xa9\xe9\x73\x12\xe6\x45\xec\xae\xdc\xc4\x49\x69\xf8\xf8\xe0\x1a\xa0\x4e\xa0\x25\xea\xba\x80\x14\xfc\xa4\x4e\x91\x43\x6b\xd3\x8f\xfb\x2f\x3a\x55\x1b\xca\x98\x1c\xa1\xd0\xe8\x08\x53\xb4\xe3\xfc\x43\x7e\x91\x55\x1b\xca\x2f\xce\xaa\x54\xef\xbb\x22\xd4\x86\x29\xab\x50\x49\x26\x77\x21\x06\x17\xaa\xed\x24\x0d\xd3\xf0\xfd\x54\x43\x55\x34\xeb\x37\x48\xb6\x03\xa4\x99\x1a\xe7\xe3\x77\xd0\xeb\xcc\x0a\x30\x89\xfd\xe3\x0d\x02\xf4\xfe\x45\x7b\x91\xff\xf0\x2e\xf3\x72\xc6\xfa\xfb\x67\x69\xef\x91\xff\x2f\x05\xfe\xdf\xbe\x48\xe2\xfc\xf8\xad\xe2\x90\x2f\x63\xb0\x5e\x27\x8d\xb7\x8f\xc5\xab\xf2\x90\x6f\x4f\xab\x32\xbf\xb9\x99\x5f\xcf\xbe\x4e\x97\xcb\xeb\xab\xcb\xe9\xdd\xd5\xcd\xe2\xeb\xe5\x97\xd9\xc7\xd9\xe2\xee\x6a\x7a\x7d\x7b\xa4\x54\x8b\xae\x49\xdb\x7a\x44\x6a\x46\xc6\x85\xa6\xcc\x04\x9f\x3f\xf2\xdf\x24\xf8\x33\xf7\x64\x1f\xbc\x8b\x9b\x75\x71\x8e\x18\x98\xb0\xbc\xf1\x6e\x7b\xb0\x79\x4e\xd0\x1f\x16\xb3\x4b\xbf\xa3\x3c\xb1\x6c\x4e\x66\x4c\x75\xd4\xed\x47\xcb\x05\xfc\xf9\xd7\xcb\xdf\xe7\xd5\x34\x85\x0c\x93\x1e\x2a\xd3\xd9\x16\x07\xc8\xc1\xdf\x01\x00\x00\xff\xff\x30\x01\x89\xb7\x82\x09\x00\x00") +var _testE2eTestingManifestsStorageCsiGcePdController_ssYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x95\x51\x6b\xe3\x46\x10\xc7\xdf\xfd\x29\x06\xf7\x59\x72\x7c\x70\x2d\x08\xfc\x60\x72\xc6\x0d\x97\x73\xcc\x25\xb4\x8f\xc7\x64\x35\xb6\xb6\x5e\xed\x6e\x67\x46\xca\xb9\xa5\xdf\xbd\x6c\x24\xa7\x72\xe2\xd0\x9a\x72\x81\x13\x18\xcc\xec\xcc\x7f\x66\x7e\x33\xd2\xee\xac\x2f\x0b\xb8\x55\x54\xda\x34\xee\x96\x74\x84\xd1\xfe\x42\x2c\x36\xf8\x02\x30\x46\x99\xb4\xd3\x51\x4d\x8a\x25\x2a\x16\x23\x00\x8f\x35\x15\x60\xc4\x66\x5b\x43\x59\x2c\x33\x13\xbc\x72\x70\x8e\x78\x24\x91\x4c\xf2\x11\xe2\xd6\x1a\x5a\x3d\xba\x8e\xff\xf1\x1d\x8f\x00\x98\xa2\xb3\x06\xa5\x80\xe9\xa3\xa7\x23\xa3\x81\x53\x14\x40\x8d\x6a\xaa\x6b\xbc\x27\x27\x9d\x01\x52\x09\x05\x6c\x4d\xcc\x4c\xa8\x63\xa3\x94\xc5\x54\x9c\x28\x79\xcd\x4a\x2b\xbb\x2c\xa9\x97\x6c\x5b\xe2\x11\x80\x52\x1d\x1d\x2a\xf5\x72\x83\xb2\xd3\xe3\x8e\x94\xcf\xd5\x06\x38\xb4\x97\x9e\x1f\xe0\xe7\x20\x0a\x9e\xf4\x21\xf0\x0e\xea\x46\x14\xee\x09\x1a\xa1\x12\x36\x81\xc1\x7a\x25\x46\xa3\x36\x78\x78\xb0\x5a\xc1\xaf\x81\x77\x2e\x60\x09\x57\x25\x79\xb5\xba\x07\xeb\x61\xf9\x71\xf1\xa4\x27\xd6\x1b\x02\xab\x8f\x84\xd0\x90\xc0\xf2\x72\x01\x9f\xfa\x1e\xe0\x96\xb8\x25\xee\xb4\x96\x1f\x5f\x1c\xe4\xf0\x99\xea\xd0\xd2\x93\x9c\x56\x56\x80\xe9\xf7\xc6\x32\xd5\xe4\x15\x1e\x2a\xf2\x60\x45\x1a\x82\xc7\x13\x09\xae\xa5\x12\xd0\x97\x70\x4f\x9b\xc0\x04\xe8\xf7\x40\x5f\x63\x90\x86\x09\xc2\xe6\x49\xaa\x26\x65\x6b\x04\x62\x60\x95\xde\x5a\x05\xd1\x55\xd7\x7c\x01\xca\xcd\x21\x71\x3f\xfa\xb9\x31\xa1\xf1\xba\x7a\x7d\x59\x32\xc1\x3e\x24\xd9\xd0\x7a\xe2\xc1\x68\xb2\xc1\x9e\x89\xc7\x28\x55\x50\xed\xc7\xd0\x3d\xb6\xc6\x2d\xa5\xf1\x71\x6e\xc3\x64\xbb\xa3\x8c\xc9\x11\x0a\x4d\x9e\xc5\x14\xed\xbb\x7c\x9a\x4f\xb3\xed\x8e\xf2\x8b\x81\x00\xf2\x76\x90\xb0\x4b\x3a\xce\xb2\x76\xf6\x7e\xfc\xd2\x9a\x34\xb1\x2c\x99\x44\x66\x29\x41\xfa\xe5\x12\xcc\x6e\xfc\xbc\xa4\x75\xe3\xdc\x3a\x38\x6b\xf6\x05\xcc\xdd\x03\xee\x65\xe0\xd1\x06\xd7\xd4\xf4\x29\xa1\x79\x91\xbb\x6b\x38\x69\x52\x5a\x3f\x3e\x3a\x06\xa8\x53\xd0\x1a\xb5\x2a\x20\x25\x3f\x49\x2a\x72\x68\x6d\x7a\x75\xcf\x20\x35\x88\x29\xda\x69\xfe\x63\x7e\xf1\x06\xa4\x7a\xdf\x0d\xa1\x36\x4c\xd9\x16\x95\x64\x76\x17\x62\x70\x61\xbb\x9f\xa5\x75\x1a\xbf\x1d\x35\x54\x45\x53\x9d\x81\xec\x10\x90\x36\xeb\xdd\x9b\xf0\xfa\xc6\x04\x98\xc4\xfe\x71\x06\x80\xde\xbf\x68\x2f\xf2\xf7\xdf\x7b\xff\xfd\x87\x69\xf0\x99\xff\x37\x02\xff\xed\xc6\x48\x70\x7e\xfa\xbf\x70\xc8\x97\x31\x58\xaf\xb3\xc6\xdb\xaf\xc5\xab\x78\xc8\xb7\xa7\xa9\x2c\x6f\x6e\x96\xd7\x8b\x2f\xf3\xf5\xfa\xfa\xea\x72\x7e\x77\x75\xb3\xfa\x72\xf9\x79\xf1\x61\xb1\xba\xbb\x9a\x5f\xdf\x3e\x23\xd5\xa2\x6b\xd2\x7d\x3d\x21\x35\x13\xe3\x42\x53\x66\x82\x4f\x7f\xf2\xdf\x24\xf8\x6f\x3c\x93\x61\xf0\x21\x6f\xd6\xe5\x79\xa6\xc0\x84\xe5\x8d\x77\xfb\xa3\xbb\xe7\x84\xfc\x71\x33\x87\xf2\x3b\xc9\x13\xd7\xcd\xc9\x8a\xa9\x8e\xba\xff\x60\xb9\x80\x3f\xff\x7a\xf9\xfa\xbc\x5a\xa6\x90\x61\xd2\x63\x32\x9d\x6d\x75\x14\x39\xfa\x3b\x00\x00\xff\xff\x5f\x2e\x46\x37\x84\x09\x00\x00") func testE2eTestingManifestsStorageCsiGcePdController_ssYamlBytes() ([]byte, error) { return bindataRead( @@ -2405,7 +2405,7 @@ func testE2eTestingManifestsStorageCsiGcePdCsiControllerRbacYaml() (*asset, erro return a, nil } -var _testE2eTestingManifestsStorageCsiGcePdNode_dsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\x4d\x6f\xe3\x36\x10\xbd\xe7\x57\x0c\xbc\xd7\x4a\xda\x5d\xa0\x3d\x08\xc8\xa1\x9b\xb8\x69\x91\x26\x5b\x6c\xb6\xed\xa1\x28\x02\x9a\x7c\x96\x08\x53\x24\x4b\x8e\x14\xfb\xdf\x17\xb4\x6c\xc7\x1f\xb2\x92\xb4\x4b\x20\x81\x41\x72\xde\x3c\x72\xde\x1b\xd3\x0b\x6d\x55\x49\xd7\x02\x8d\xb3\x0f\xe0\x0b\xe1\xf5\x1f\x08\x51\x3b\x5b\x92\xf0\x3e\x16\xdd\x87\x8b\x06\x2c\x94\x60\x51\x5e\x10\x59\xd1\xa0\x24\x19\x75\x56\x49\x64\x5e\x65\xd6\x29\x5c\x44\x0f\x99\x56\x23\x0c\x24\xbb\x90\x3e\x13\x35\x82\x65\xfd\xab\x98\xc1\xc4\x7e\x82\x12\x64\x49\x95\xf4\x99\x74\x8d\x6f\x19\x99\x4f\xc9\x22\xc3\x72\xa6\x74\x5c\x64\x09\x59\x05\xdd\x21\x5c\x10\x31\x1a\x6f\x04\x63\x03\xb7\x47\x23\x0d\x73\x80\xfc\x56\x6c\xa2\x2d\xe9\x34\xde\xd1\xcf\x2e\x32\x59\xf0\x93\x0b\x0b\x6a\xda\xc8\x34\x03\xb5\x11\x8a\xe6\x2e\x90\xb6\x8c\x20\x24\x6b\x67\xe9\x49\x73\x4d\x7f\xba\xb0\x30\x4e\x28\xfa\x45\xc1\xb2\xe6\x15\x69\x4b\x37\xb7\xd3\x1d\x5e\xd4\x56\x82\x34\x53\x80\x37\x42\x22\xd2\xcd\xd5\x94\xee\x36\x67\xa0\x07\x84\x0e\xa1\xc7\xba\xb9\x3d\x59\xc8\xe9\x0b\x1a\xd7\x61\x07\xc7\xb5\x8e\x14\xf0\x4f\xab\x03\x1a\x58\xa6\xa7\x1a\x96\x74\x8c\x2d\x68\xbd\x12\x9d\xe9\xa0\x48\x58\x45\x33\xcc\x5d\x00\x09\xbb\x22\x2c\xbd\x8b\x6d\x00\xb9\xf9\x0e\xaa\x01\x07\x2d\x23\x79\x17\x38\xe6\x9b\xe9\xda\x45\xbe\xef\x4f\x5f\x12\x87\x76\x9b\x59\x3a\xcb\x42\x5b\x84\xbd\x8b\xce\xf6\x54\xd0\xdf\x67\x16\x50\xe9\xc8\x41\x84\xdd\x26\x22\xdd\x88\x0a\xa9\x22\x21\xd7\xae\xa8\x16\xc8\x02\x0c\x44\x44\x91\x02\x93\x6e\x4e\xa2\xcb\xee\x43\xfe\x31\x7f\x9f\x55\x0b\xe4\xef\xf7\xa0\x44\xa8\xf6\xf2\xf7\x1c\x26\x59\xd6\x5d\x7e\x3f\x39\x9d\x4d\xe8\x42\xa9\x80\x18\x2f\x53\xaa\xf4\x97\x47\x27\x17\x03\x7b\x17\xed\x0c\x06\xbc\x63\x90\x0a\x9c\x79\xc1\xf5\x65\xd1\x89\x50\x18\x3d\x2b\x36\x5b\x0a\x6f\xda\x4a\xdb\x58\x78\x95\xaf\x01\xd9\x05\x51\x21\x4f\x54\xb5\x1b\xcc\x61\xf4\x1c\x72\x25\x0d\x0e\xa9\xfb\x80\x07\x76\xfe\x70\x92\x08\xcb\x67\x39\x3e\x0f\xe9\x9a\x46\x24\x8b\xfe\x35\x29\x66\xda\x16\xb1\x9e\x7c\x47\x93\x4c\xa6\xff\xa1\xa1\x2c\xcc\xa9\xd8\x27\x3f\x4c\xef\x35\x7b\xd2\x1d\xf4\x47\xf8\x7b\x8f\x05\x6c\x77\x7c\xf1\x7d\xf1\x6f\x7f\xff\x34\x7d\xbc\xff\x7c\x3d\x7d\xbc\xff\xf1\x6e\x7a\xc4\xbb\x13\xa6\xc5\x4f\xc1\x35\xa7\x07\x9a\x6b\x18\xf5\x05\xf3\xd3\x95\xcd\xda\x6f\x82\xeb\x72\x6d\xce\x3c\x69\xe4\x5e\x34\xd8\xdb\xda\x39\xd3\x36\xb8\x73\xad\xe5\x13\x45\xf4\xc4\xfa\x3a\x65\x4a\x87\xa3\x0c\x4d\x0a\xea\xd1\x53\xb9\x06\x83\x0f\x74\x30\x0e\xb1\xbf\xf5\xc4\x1a\x9b\xe6\xb8\xd7\x6d\xfa\x11\x21\xdb\xa0\x79\x75\xe5\x2c\x63\xc9\xc7\xc2\xd0\x9d\x36\xa8\xa0\x0e\x2c\x48\xa3\x5e\x7a\x5d\xc3\x2b\xbb\xf7\xf9\x0f\xf9\xc7\xff\x67\x2c\x58\xe5\x9d\xb6\x7c\xd9\x5a\xbd\x2c\xcf\x5a\xeb\xe5\x12\x6d\x5d\x37\x7e\xc1\x47\x06\x1c\xdc\x19\x9c\x17\xd5\xba\x04\x25\x4d\x3e\x69\xa5\x03\xd6\x4d\x5a\x98\x63\xfe\xdf\x40\x1c\x0a\x9d\x96\x78\x21\x58\xa1\x3b\x58\x7d\x47\x5f\x6b\xd0\xdc\x19\xe3\x9e\xb4\xad\xfa\xbd\x91\x44\xc0\xb6\x9d\x2b\x62\x47\x1c\x74\x55\x21\xac\xfb\x30\xb5\x0a\x9d\x50\x0d\xcd\x83\x6b\x8e\xc0\x76\xfd\x78\x90\x61\x0a\xcc\x42\x6b\x10\x33\xb0\x1c\x61\x09\x96\x45\x7b\x4c\x75\x00\xc5\xe8\xd9\x08\x4a\xaa\xce\x38\x4a\xd2\xc6\x99\xd2\x6d\x5c\xd4\xda\xf3\x10\x71\x15\x47\x42\x9f\x57\x7b\xc5\x0d\x7c\x43\x8d\xd8\x39\x5d\xf4\x1a\xe8\xd0\x82\x83\xd2\xdb\xf6\xfe\xc7\x0d\xde\xaa\x38\x08\xe2\x95\x47\x49\xd7\x6b\xed\xb9\xb0\x3a\x61\x31\x2c\xf7\xb7\x10\x78\x53\xba\x41\x8d\xff\x97\xe3\x9e\xf9\xaa\x1b\x23\xf3\x39\x5c\x05\x08\xc6\x09\xa9\x41\xef\x8c\x92\x3a\x16\xc5\xb9\x63\x7f\x33\x83\x0d\x99\xeb\x45\x63\x8d\x1e\x61\xd0\x65\x2f\x95\xef\xac\xfb\x46\x53\x0d\x5a\xf1\x55\xa9\x4e\x2c\x3a\x9a\x67\xd0\xaf\x2f\xe5\x39\xf4\xf1\x28\xfe\xb1\xe5\x87\xa1\xdf\x51\xcd\xec\x63\x59\xac\x25\x1b\x2c\x18\x31\x49\x53\x39\x19\x0b\xe9\xac\x84\xe7\xf5\x87\xb9\xae\xda\xcd\xa3\x27\x55\x96\x33\x61\x55\xc6\xce\x60\x33\xb9\xc3\x7b\x00\x68\x92\x1e\x1d\x5a\x18\x92\x22\x62\x92\xd3\xd7\xf4\xe6\x7e\xd2\xc6\xd0\x26\x02\x84\x0e\x61\xc5\xb5\xb6\x55\x4e\xf7\x4e\x21\xbd\xcf\xbc\xb3\xe9\x41\x1e\x6b\xd7\x1a\xb5\x03\x9c\x81\xa2\xac\xa1\x5a\x03\x45\xce\x92\x30\x86\xd2\x7b\x66\xf7\xe2\x7e\x66\xb1\x6b\x5c\x19\x39\x9f\xe6\x5c\x28\x69\xba\xd4\x91\xb7\x77\x91\x02\x1f\x0e\x7e\x5b\xa5\x71\x78\x76\x17\x4b\x32\xda\xb6\xcb\x7f\x03\x00\x00\xff\xff\x65\x92\xf3\xbe\xd3\x0d\x00\x00") +var _testE2eTestingManifestsStorageCsiGcePdNode_dsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\x5f\x6f\xe3\xb6\x13\x7c\xf7\xa7\x58\xf8\x5e\x7f\x92\xee\xf0\x43\x51\x40\x40\x1e\x7a\x17\x37\x2d\xd2\xe4\x8a\xcb\xb5\x7d\x28\x8a\x80\x26\xc7\x12\x61\x8a\x64\xc9\x95\x62\x7f\xfb\x82\x96\xed\xf8\x8f\xac\x24\xed\x11\x48\x60\x90\xdc\xd9\x21\x77\x66\x4d\x2f\xb5\x55\x25\x5d\x0b\x34\xce\x3e\x80\x27\xc2\xeb\xdf\x11\xa2\x76\xb6\x24\xe1\x7d\x2c\xba\x0f\x93\x06\x2c\x94\x60\x51\x4e\x88\xac\x68\x50\x92\x8c\x3a\xab\x24\x32\xaf\x32\xeb\x14\x26\xd1\x43\xa6\xd5\x08\x03\xc9\x2e\xa4\xcf\x44\x8d\x60\x59\xff\x22\xe6\x30\xb1\x9f\xa0\x04\x59\x52\x25\x7d\x26\x5d\xe3\x5b\x46\xe6\x53\xb2\xc8\xb0\x9c\x29\x1d\x97\x59\x42\x56\x41\x77\x08\x13\x22\x46\xe3\x8d\x60\x6c\xe1\x0e\x68\xa4\x61\x8e\x90\xdf\x8a\x4d\xb4\x23\x9d\xc6\x3b\xfa\xc9\x45\x26\x0b\x7e\x72\x61\x49\x4d\x1b\x99\xe6\xa0\x36\x42\xd1\xc2\x05\xd2\x96\x11\x84\x64\xed\x2c\x3d\x69\xae\xe9\x0f\x17\x96\xc6\x09\x45\x3f\x2b\x58\xd6\xbc\x26\x6d\xe9\xe6\x76\xb6\xc7\x8b\xda\x4a\x90\x66\x0a\xf0\x46\x48\x44\xba\xf9\x34\xa3\xbb\xed\x19\xe8\x01\xa1\x43\xe8\xb1\x6e\x6e\xcf\x16\x72\xfa\x82\xc6\x75\xd8\xc3\x71\xad\x23\x05\xfc\xdd\xea\x80\x06\x96\xe9\xa9\x86\x25\x1d\x63\x0b\xda\xac\x44\x67\x3a\x28\x12\x56\xd1\x1c\x0b\x17\x40\xc2\xae\x09\x2b\xef\x62\x1b\x40\x6e\xb1\x87\x6a\xc0\x41\xcb\x48\xde\x05\x8e\xf9\x76\xba\x76\x91\xef\xfb\xd3\x97\xc4\xa1\xdd\x65\x96\xce\xb2\xd0\x16\xe1\xe0\xa2\xb3\x03\x15\xf4\xf7\x99\x05\x54\x3a\x72\x10\x61\xbf\x89\x48\x37\xa2\x42\xaa\x48\xc8\xb5\x2b\xaa\x25\xb2\x00\x03\x11\x51\xa4\xc0\xa4\x9b\xb3\xe8\xb2\xfb\x90\xff\x3f\x7f\x9f\x55\x4b\xe4\xef\x0f\xa0\x44\xa8\x0e\xf2\xf7\x1c\xa6\x59\xd6\x5d\x7d\x37\x3d\x9f\x4d\xe8\x42\xa9\x80\x18\xaf\x52\xaa\xf4\x97\x47\x27\x97\x03\x7b\x97\xed\x1c\x06\xbc\x67\x90\x0a\x9c\x79\xc1\xf5\x55\xd1\x89\x50\x18\x3d\x2f\xb6\x5b\x0a\x6f\xda\x4a\xdb\x58\x78\x95\x6f\x00\xd9\x05\x51\x21\x4f\x54\xb5\x1b\xcc\x61\xf4\x02\x72\x2d\x0d\x8e\xa9\xfb\x80\x07\x76\xfe\x78\x92\x08\xab\x67\x39\x3e\x0f\xe9\x9a\x46\x24\x8b\xfe\x39\x2d\xe6\xda\x16\xb1\x9e\xfe\x8f\xa6\x99\x4c\xff\x43\x43\x59\x58\x50\x71\x48\x7e\x98\xde\x6b\xf6\xa4\x3b\xe8\x8f\xf0\xd7\x01\x0b\xd8\xee\xf4\xe2\xfb\xe2\xdf\xfe\xf6\x71\xf6\x78\xff\xf9\x7a\xf6\x78\xff\xc3\xdd\xec\x84\x77\x27\x4c\x8b\x1f\x83\x6b\xce\x0f\xb4\xd0\x30\xea\x0b\x16\xe7\x2b\xdb\xb5\x5f\x05\xd7\xe5\xc6\x9c\x79\xd2\xc8\xbd\x68\x70\xb0\xb5\x73\xa6\x6d\x70\xe7\x5a\xcb\x67\x8a\xe8\x89\xf5\x75\xca\x94\x0e\x27\x19\x9a\x14\xd4\xa3\xa7\x72\x0d\x06\x1f\xe9\x60\x1c\xe2\x70\xeb\x99\x35\xb6\xcd\xf1\xa0\xdb\xf4\x23\x42\xb6\x41\xf3\xfa\x93\xb3\x8c\x15\x9f\x0a\x43\x77\xda\xa0\x82\x3a\xb2\x20\x8d\x7a\xe9\x75\x0d\xaf\xec\xde\xe7\xdf\xff\x57\x63\xc1\x2a\xef\xb4\xe5\xab\xd6\xea\x55\x79\xd1\x5a\x2f\x97\x68\xe7\xba\xf1\x0b\x3e\x31\xe0\xe0\xce\xe0\xbc\xa8\x36\x25\x28\x69\xfa\x51\x2b\x1d\xb0\x69\xd2\xc2\x9c\xf2\xff\x06\xe2\x50\xe8\xb4\xc4\x0b\xc1\x0a\xdd\xd1\xea\x3b\xfa\x5a\x83\x16\xce\x18\xf7\xa4\x6d\xd5\xef\x8d\x24\x02\x76\xed\x5c\x11\x3b\xe2\xa0\xab\x0a\x61\xd3\x87\xa9\x55\xe8\x84\x6a\x68\x11\x5c\x73\x02\xb6\xef\xc7\x83\x0c\x53\x60\x16\x5a\x83\x98\x81\xe5\x08\x4b\xb0\x2c\xda\x53\xaa\x03\x28\x46\xcf\x47\x50\x52\x75\xc6\x51\x92\x36\x2e\x94\x6e\xeb\xa2\xd6\x5e\x86\x88\xeb\x38\x12\xfa\xbc\xda\x2b\x6e\xe0\x1b\x6a\xc4\xce\xe9\xa2\x37\x40\xc7\x16\x1c\x94\xde\xae\xf7\x3f\x6e\xf1\xd6\xc5\x51\x10\xaf\x3d\x4a\xba\xde\x68\xcf\x85\xf5\x19\x8b\x61\xb9\xbf\x85\xc0\x9b\xd2\x0d\x6a\xfc\xdf\x1c\xf7\xc2\x57\xdd\x18\x99\xcf\xe1\x53\x80\x60\x9c\x91\x1a\xf4\xce\x28\xa9\x53\x51\x5c\x3a\xf6\x37\x33\xd8\x90\xb9\x5e\x34\xd6\xe8\x11\x06\x5d\xf6\x52\xf9\x2e\xba\x6f\x34\xd5\xa0\x15\x5f\x95\xea\xcc\xa2\xa3\x79\x06\xfd\xfa\x52\x9e\x63\x1f\x8f\xe2\x9f\x5a\x7e\x18\xfa\x1d\xd5\xcc\x3e\x96\xc5\x46\xb2\xc1\x82\x11\x93\x34\x95\x93\xb1\x90\xce\x4a\x78\xde\x7c\x58\xe8\xaa\xdd\x3e\x7a\x52\x65\x39\x13\x56\x65\xec\x0c\xb6\x93\x7b\xbc\x07\x80\xa6\xe9\xd1\xa1\x85\x21\x29\x22\xa6\x39\x7d\x4d\x6f\xee\x27\x6d\x0c\x6d\x23\x40\xe8\x10\xd6\x5c\x6b\x5b\xe5\x74\xef\x14\xd2\xfb\xcc\x3b\x9b\x1e\xe4\xb1\x76\xad\x51\x7b\xc0\x39\x28\xca\x1a\xaa\x35\x50\xe4\x2c\x09\x63\x28\xbd\x67\xf6\x2f\xee\x67\x16\xfb\xc6\x95\x91\xf3\x69\xce\x85\x92\x66\x2b\x1d\x79\x77\x17\x29\xf0\xe1\xe8\xb7\x55\x1a\xc7\x67\x77\xb1\x24\xa3\x6d\xbb\x9a\xfc\x13\x00\x00\xff\xff\xd3\x16\xd5\xf9\xd4\x0d\x00\x00") func testE2eTestingManifestsStorageCsiGcePdNode_dsYamlBytes() ([]byte, error) { return bindataRead( @@ -2425,7 +2425,7 @@ func testE2eTestingManifestsStorageCsiGcePdNode_dsYaml() (*asset, error) { return a, nil } -var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathAttacherYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x53\xc1\x6e\xe3\x36\x10\xbd\xeb\x2b\x06\xe9\xb5\xb4\x9a\xb4\x01\x0a\x01\x39\x04\x49\x0e\x41\xd3\xb4\x80\x17\x7b\x1f\x53\x63\x69\x60\x8a\xe4\x92\x43\xc5\xfa\xfb\x05\x65\x6f\x4c\xd9\xbb\x1b\xac\x8e\xc3\xf7\x1e\xdf\x3c\x3e\xed\xd8\xb6\x0d\xac\x29\x8c\xac\xa9\x42\xcf\x9f\x29\x44\x76\xb6\x81\xf1\xba\x1a\x48\xb0\x45\xc1\xa6\x02\xb0\x38\x50\x03\x3a\xb2\xea\x5d\x14\x8f\xd2\x2b\x14\x41\xdd\x53\xa8\x00\x0c\x6e\xc8\xc4\x8c\x03\x40\xef\x7f\x04\x8c\x9e\x74\x06\x45\x32\xa4\xc5\x85\x0f\x09\x00\xde\x05\x39\x0a\xab\xa3\x89\x36\x0d\xc3\x34\x4f\x0e\xc7\x0d\x5c\xdf\xfc\xf9\xd7\x6d\x55\x29\xa5\xaa\xe3\x42\x82\x42\xdb\x64\xd6\x24\x8b\xa5\xd0\xfb\x58\xff\xc2\x66\x27\xc3\x73\x40\xaf\x33\xf4\xea\xbb\xd8\xab\x0a\x20\x90\x37\xac\x31\x36\x70\x7d\xb1\xe5\x80\xa2\xfb\x97\x22\xa7\x0f\x16\x17\x1a\xbc\x41\xa1\x23\xbb\x30\x9c\x3f\xb3\x10\xfa\x40\x0a\xe0\xdb\x1e\x33\x74\xbb\x65\xcb\x32\x9d\xc8\xde\xb5\xf7\x17\xc3\xbc\xcd\x97\xc4\x81\xda\xc7\x14\xd8\x76\x6b\xdd\x53\x9b\x0c\xdb\xee\xb9\xb3\xee\x7d\xfc\xb4\x27\x9d\x24\x87\x5b\x30\xd5\xc1\xdf\x7a\x11\xc0\xe9\x9b\xa3\x78\xda\xfb\x40\x31\x3f\x4b\x3c\x3f\x57\xb0\xa3\x69\x7e\xac\xb3\x03\x00\xe7\x29\x60\x96\x84\x67\x7b\x71\x38\xa2\x49\x74\xa1\x96\xf5\xca\x64\xbc\x49\x1d\x2f\xc9\xe2\xbc\x33\xae\x9b\xfe\xc9\xd7\xee\xd2\x86\x82\x25\xa1\xb8\x62\x57\x67\x56\x6e\xc8\x11\x7f\x2c\xc2\xbd\xd6\x2e\x59\x79\x7d\xaf\xce\x22\x6d\x00\xed\xac\x20\x5b\x0a\x85\x1b\x55\x34\xed\x0c\x9e\x3f\x1e\xb0\xa3\x06\x3a\x1d\xf2\xb5\xbb\xbf\xa3\x8a\x82\x1d\xdb\x4e\xe9\xc8\x75\x49\x6a\xc6\x9b\xd5\xcd\xea\x8f\x82\x8b\xa1\x3b\x5b\x5b\x81\x52\xe3\xdd\xed\xc5\x6c\xd6\x69\xdb\x9c\xfc\x5d\x7d\x14\x5e\x45\xa7\x77\x05\x32\x92\x4e\x81\x65\x7a\x70\x56\x68\x2f\x4b\xe1\xdf\xe0\x53\xcf\x11\x38\x82\x25\x4d\x31\x62\x98\xc0\x59\x33\xc1\xd6\x05\x88\x53\x14\x1a\x22\xbc\xb1\xf4\xb0\x7e\x7a\x61\x9b\xf6\xbf\xc3\x5b\x4f\x81\xce\x44\xac\xb3\xca\x07\x1e\xd9\x50\x47\x2d\x44\x6e\x49\x63\x28\x72\x03\x8d\xd6\x3a\x01\xd4\xf9\x16\x48\x96\xf7\xd0\xba\x01\xd9\x42\xb6\x4b\x72\x26\xa8\x03\xa1\x50\x0b\x9b\x09\x0a\xdd\x87\xf5\x33\xb4\x81\x47\x2a\xa4\x57\x0b\xe6\x09\xdc\x80\x84\x54\xfa\x1c\x9d\x49\x03\xfd\x9b\x1f\x3a\x2e\xdb\x3d\xe4\xd9\xff\x28\x7d\x03\x39\xc0\x85\xe0\xe1\x91\x0f\x1e\x55\xcb\xa1\xaa\x4a\xb5\x45\x1f\x72\xb7\x66\x95\xa5\xa3\x83\xee\x88\xa1\x36\xbc\xa9\x73\x1d\x0d\x49\x7d\xa8\x6d\xac\xcb\x2a\x2f\x4b\x3c\x79\x6a\xe0\x91\xc3\xfc\xcf\x4d\xff\x85\x87\x39\x92\xea\x27\xd6\xbe\x06\x00\x00\xff\xff\x76\x8a\x26\x3e\xfe\x05\x00\x00") +var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathAttacherYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x53\xc1\x6e\xdb\x3a\x10\xbc\xeb\x2b\x16\x79\xd7\x47\xbb\x49\x1b\xa0\x10\x90\x43\x90\xe4\x10\x34\x4d\x0b\xb8\xe8\x7d\x4d\xad\xa5\x85\x29\x92\x25\x97\x8a\xf5\xf7\x05\x65\x37\xa6\xec\xb6\x41\x05\xf8\xb2\x9c\x19\xce\x0e\xc7\x5b\xb6\x4d\x0d\x2b\x0a\x03\x6b\xaa\xd0\xf3\x77\x0a\x91\x9d\xad\x61\xb8\xac\x7a\x12\x6c\x50\xb0\xae\x00\x2c\xf6\x54\x83\x8e\xac\x3a\x17\xc5\xa3\x74\x0a\x45\x50\x77\x14\x2a\x00\x83\x6b\x32\x31\xe3\x00\xd0\xfb\x3f\x01\xa3\x27\x9d\x41\x91\x0c\x69\x71\xe1\x4d\x02\x80\x77\x41\x0e\xc2\xea\x60\xa2\x49\x7d\x3f\x4e\x93\xfd\x71\x0d\x97\x57\xef\x3f\x5c\x57\x95\x52\xaa\x3a\x2c\x24\x28\xb4\x49\x66\x45\x32\x5b\x0a\xbd\x8f\xcb\x7f\xd8\xec\x68\x78\x0a\xe8\x79\x82\x5e\xfc\x16\x7b\x51\x01\x04\xf2\x86\x35\xc6\x1a\x2e\xcf\xb6\xec\x51\x74\xf7\x54\xe4\xf4\xc6\xe2\x42\xbd\x37\x28\x74\x60\x17\x86\xf3\x67\x66\x42\x6f\x48\x01\xfc\xda\x63\x82\x6e\x36\x6c\x59\xc6\x23\xd9\xbb\xe6\xf6\x6c\x98\xb7\xf9\x91\x38\x50\x73\x9f\x02\xdb\x76\xa5\x3b\x6a\x92\x61\xdb\x3e\xb6\xd6\xbd\x8e\x1f\x76\xa4\x93\xe4\x70\x0b\xa6\xda\xfb\x5b\xcd\x02\x38\x7e\x53\x14\x0f\x3b\x1f\x28\xe6\x67\x89\xa7\xe7\x0a\xb6\x34\x4e\x8f\x75\x72\x00\xe0\x3c\x05\xcc\x92\xf0\x68\xcf\x0e\x07\x34\x89\xce\xd4\xb2\x5e\x99\x8c\x37\xa9\xe5\x39\x59\x9c\x77\xc6\xb5\xe3\xa7\x7c\xed\x36\xad\x29\x58\x12\x8a\x0b\x76\xcb\xcc\xca\x0d\x39\xe0\x0f\x45\xb8\xd5\xda\x25\x2b\xcf\xaf\xd5\x99\xa5\x0d\xa0\x9d\x15\x64\x4b\xa1\x70\xa3\x8a\xa6\x9d\xc0\xf3\xc7\x3d\xb6\x54\xc3\xf6\x63\x5c\xb4\x3a\xe4\xab\x23\xb7\x2a\x8a\x0b\xd8\xd2\xb2\x24\xd5\xc3\xd5\xe2\x6a\xf1\xae\xe0\x62\x68\x4f\xd6\x56\xa0\xd4\x70\x73\x7d\x36\x9b\x74\x9a\x26\x27\x7f\x93\x45\xf3\x6f\x11\x9d\xde\x16\xc8\x48\x3a\x05\x96\xf1\xce\x59\xa1\x9d\xcc\x85\xff\x83\x6f\x1d\x47\xe0\x08\x96\x34\xc5\x88\x61\x04\x67\xcd\x08\x1b\x17\x20\x8e\x51\xa8\x8f\xf0\xc2\xd2\xc1\xea\xe1\x89\x6d\xda\xfd\x0f\x2f\x1d\x05\x3a\x11\xb1\xce\x2a\x1f\x78\x60\x43\x2d\x35\x10\xb9\x21\x8d\xa1\xc8\x0d\x34\x5a\xeb\x04\x50\xe7\x5b\x20\x59\xde\x41\xe3\x7a\x64\x0b\xd9\x2e\xc9\x89\xa0\x0e\x84\x42\x0d\xac\x47\x28\x74\xef\x56\x8f\xd0\x04\x1e\xa8\x90\x5e\xcc\x98\x47\x70\x0d\x12\x52\xe9\x73\x70\x26\xf5\xf4\x39\x3f\x74\x9c\xb7\xbb\xcf\xb3\xaf\x28\x5d\x0d\x39\xc0\x99\xe0\xfe\x91\xf7\x1e\x55\xc3\xa1\xaa\x4a\xb5\x59\x1f\x72\xb7\x26\x95\xb9\xa3\xbd\xee\x80\x61\x69\x78\xbd\xcc\x75\x34\x24\xcb\x7d\x6d\xe3\xb2\xac\xf2\xbc\xc4\xa3\xa7\x1a\xee\x39\x4c\xff\xb9\xf1\x4b\xb8\x9b\x22\xa9\xfe\x62\xed\x67\x00\x00\x00\xff\xff\x6b\x30\xa8\x26\xfe\x05\x00\x00") func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathAttacherYamlBytes() ([]byte, error) { return bindataRead( @@ -2465,7 +2465,7 @@ func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathDriverinfoYaml( return a, nil } -var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathPluginYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x5f\x6f\xdb\x36\x10\x7f\xf7\xa7\x38\x24\x05\xda\x01\x95\x95\xf4\x1f\x52\x01\x7e\x58\x93\x6c\x2b\xd6\x26\xc1\x92\x75\x8f\x01\x2d\x9e\xad\x43\x28\x52\x20\x4f\x4a\xbc\x4f\x3f\x1c\x65\x3b\x92\xad\x38\x6e\xb1\x01\xf3\x53\x4b\xde\x3f\xde\xdd\xef\x77\xa7\x1c\xc2\x35\xfa\x86\x72\x04\x8d\x33\xb2\xa8\xa1\x40\x8f\xaf\xa1\x32\x75\x80\xd0\x5e\x5d\xa8\x12\x61\x8a\xc6\xdd\x03\x59\xb8\x66\xc5\x38\xab\xcd\x35\xf2\xeb\xd1\x21\x28\x8f\x60\x11\x35\x6a\x70\xd6\x2c\x60\x8a\xb9\xaa\x03\x82\x9b\x41\xee\xac\x26\x26\x67\x01\x1f\x2a\xa3\xa2\x75\xb2\xa3\x43\x28\x98\xab\x90\xa5\xe9\x9c\xb8\xa8\xa7\xe3\xdc\x95\xe9\x5d\x3d\x45\x6f\x91\x31\x74\xff\x49\x21\xd4\x18\xd2\x0f\x1f\x3f\x1c\x9d\x8c\x46\x77\x64\x75\xb6\x8a\x77\xa4\x2a\xfa\x86\x3e\x90\xb3\x19\x34\xc7\xa3\x12\x59\x69\xc5\x2a\x1b\x01\x58\x55\x62\x06\x79\xa0\xa4\x70\x81\x2b\xc5\x45\x65\xea\x39\xd9\x11\x80\x51\x53\x34\x41\x84\x00\x54\x55\x0d\x4a\x85\x0a\x73\x91\x08\x68\x30\x67\xe7\x77\x4b\x03\x54\xce\xf3\xd2\x64\xb2\xf4\xad\xeb\xb2\x5c\xc4\x93\xf6\x3a\x83\xe3\x37\x6f\xdf\xbd\x1f\x25\x49\xb2\x7a\xc6\x63\x1a\x7b\x4f\x51\x55\x15\xd2\x7d\xdf\xf3\x18\xe9\xba\x50\x19\x1c\x6c\x0b\x1e\x8c\x00\x0e\xe1\xd2\x22\x78\xac\x0c\xe5\x2a\xd6\x2a\x8b\xa7\xbf\xb9\xc0\x20\xa2\xa0\x3d\x35\xe8\xdb\x32\xde\x3b\x7f\x17\xe0\xbe\x40\x0b\xd8\xa0\x5f\x70\x41\x76\x0e\xbe\xb6\x21\x2a\x39\x0b\x0a\x02\xd9\xb9\x41\xb0\x4e\xe3\x18\xfe\x42\x50\x79\x41\xd8\x20\x70\xa1\x18\xa6\x0b\x08\xac\x3c\x8b\x1a\x31\x38\x9b\x23\x28\xab\x81\x0b\xb4\xd1\x44\xee\x12\xe3\x72\xc5\x08\xca\x18\x70\x5c\xa0\x87\xca\xe9\x00\x0d\x29\x20\xcb\xe8\x93\xca\x69\x50\xb3\x19\x59\x62\x49\xe6\x32\xf6\x90\xc1\xf1\x56\x75\x4a\xc5\x79\xf1\xa5\x53\xdc\x5d\x05\x63\x2c\x2b\xa3\x18\x97\xaa\x9d\x4c\xcb\xcf\xf4\xac\xec\xb2\x03\xb0\x2a\x80\xfc\x72\x67\x59\x9a\xdc\x77\x74\x57\xfd\x20\x39\x4a\xda\xfc\x26\x1e\xe7\x14\xd8\x2b\xbf\x96\x02\xa0\x52\xcd\x31\x83\x79\xee\xc7\xe4\xd2\xbb\x93\x90\x04\x56\x73\xb2\xf3\x24\x0f\x94\x8a\xf3\x41\x0b\x59\x73\x3c\x7e\x3b\x3e\xea\x18\x52\x7e\xde\x71\xdf\x86\x90\x24\xcd\xe4\xfd\xd6\x99\x18\x55\x5a\x7b\x0c\x61\x92\x2e\xbd\x8c\x83\xcb\xef\xb6\x24\x05\x90\x06\x79\xed\x56\x20\x9d\x48\x22\x26\x69\xa3\x7c\x6a\x68\x9a\x2e\x45\xd2\x36\x35\x21\xed\xa6\x6b\xc8\x70\xc0\xbc\xf6\xc4\x8b\x53\x67\x19\x1f\xb8\x1f\xf1\x21\xdc\x14\x14\x80\x02\x58\xcc\x31\x04\xe5\x17\x6d\x53\xce\x9c\x87\xb0\x08\x8c\x65\x80\x7b\xe2\x02\xae\xcf\xbf\x90\xad\x1f\x5e\x4b\xa3\x7a\xdc\x30\x62\x25\x4a\x4f\x0d\x19\x9c\xa3\x86\x40\x1a\x73\xe5\x3b\x65\x82\x5c\x59\xeb\x18\x54\x2e\x5e\xa0\xb6\xf4\x00\xda\x95\x8a\x2c\x48\xb8\xc8\x1b\x06\x73\x8f\x8a\x51\x4b\x6b\x77\xec\x9e\x5e\x7f\x5e\x21\x67\x6d\x7a\xdc\xd3\x7c\x14\xce\x80\x7d\xdd\x8d\x13\x6d\xb3\x59\xad\xb6\x61\x7e\xff\xf3\xd3\xf9\xed\xc5\xe5\xd9\xf9\xed\xc5\xcf\x5f\xcf\x7b\x22\x00\x8d\x32\x35\xfe\xe2\x5d\x99\x6d\x5c\x00\xcc\x08\x8d\xfe\x03\x67\xdb\x37\xd2\xc8\x3d\xc6\xdc\x16\x88\xca\x57\x8a\x8b\x2c\x36\xf6\x58\x7a\x4e\x38\xa5\x23\xda\x38\x53\x97\xf8\xd5\xd5\x96\x7b\x7d\x96\x40\x29\x67\xad\xb2\x54\xbc\x67\xbe\x7d\x53\x9b\xd4\x44\x93\x7f\x52\xb1\xdb\x62\x03\x16\x7a\x1d\xb8\xcb\x8e\xf4\x9f\x60\x7a\x43\xa8\x4b\xa5\xeb\xeb\x2d\xb0\xae\x1a\x77\x6f\x7c\xf6\x89\x41\x40\xf9\x6e\x7c\x94\xf8\xfc\xcd\x33\xc0\x3c\x48\x96\x88\x16\xbf\x93\x95\x95\xb1\xe0\xe5\xee\x24\x8c\xc9\x1d\x6c\x2b\x34\x93\xf7\x03\xa7\x68\x75\xe5\xc8\xf2\xe4\xc5\xab\xd3\xeb\xcf\xb7\xe7\x17\x67\x57\x97\x9f\x2f\x6e\x7e\x1a\x10\x95\xa2\x92\x9e\xbc\x78\xd5\x6f\xb1\x0d\x51\xc1\x20\xb6\xa8\xd3\x34\x9b\xa1\x47\x21\x70\x76\x30\x38\xb3\xd7\x2c\xb5\x24\x28\x79\x4a\x64\x88\x54\x63\x65\xdc\x62\xc3\x74\x02\xf7\x08\x85\x6a\x10\x14\x30\x06\x0e\xed\xc8\xc8\x0b\xcc\xef\x42\xe4\x4a\x30\x54\x12\x87\xf1\x76\xf8\xa5\x7a\x68\x7b\x30\x54\xe8\x45\x74\x72\x7c\x74\xb0\x0f\xa2\xba\x79\x19\xc2\x53\x16\x09\x20\x4b\xd3\x5d\x64\xf8\xff\x06\xe7\x4e\x56\xdd\xc1\x42\x9d\x05\x66\xf5\xd0\x35\x95\x5d\xc5\xed\xe5\xe3\xc9\xc7\x93\x01\x1c\x15\xa8\x0c\x17\x7f\x6f\xf8\x71\xec\x72\x67\x32\xb8\x39\xbd\xea\xdc\x18\x6a\xd0\x62\x08\x57\xde\x4d\xb1\x1f\xda\x4c\x91\xa9\x3d\xde\x14\x1e\x43\xe1\x8c\xce\xa0\x3f\xae\x64\x5f\xfc\x15\x79\x33\x6d\x55\x8b\xf5\xa1\x20\x56\x5b\xd7\xd0\x9d\xac\x13\xa4\xcc\x19\x1a\xb5\xb8\x46\x59\x52\x65\xa3\x38\xea\xc9\x30\x95\xe8\x6a\x5e\x5f\xbf\xed\x3f\x11\x3d\x39\xbd\xbe\x7c\xb3\x07\x3f\x3e\xc7\x90\x3b\x39\x72\x53\x79\x6b\xea\x3a\x1d\x36\xac\xb5\xe2\xde\x55\x6a\x1e\xd9\x32\x83\x4f\xa4\xc9\x63\x2e\xff\x51\x66\xd0\x77\xd4\x89\x34\xf2\xbd\xfe\xdb\xa9\xff\x2f\x84\xb0\xb4\xf4\x8c\xff\x27\xd9\x7d\x90\xdf\x9f\xb6\xa3\xb1\x19\x54\xd7\xd8\xf4\x34\x57\xb8\x5f\xb5\x70\x52\x49\x0f\xff\x97\x53\x71\xf7\xbc\x59\xc5\x11\xc3\x90\x71\x73\xbc\x73\x07\xdc\x77\xdb\x13\xb9\x16\x30\x89\xa0\x67\x12\x41\x3f\xea\xbe\xb0\xb7\xd9\x0a\xc9\xc7\x97\xf5\xb1\xb1\xb3\x45\x7a\x8b\x61\x1f\x71\x8b\x0a\x33\x38\x8b\xfd\xe1\xfc\xe2\xd2\x9f\xc6\x6d\x6b\xb4\x47\xba\xbe\x37\x94\x4d\xb4\xec\xeb\xfa\x09\x7c\xfc\x58\x26\x6e\x97\xbb\xcc\x62\x57\x28\x5b\x21\x3c\xb9\x00\xfd\x58\x10\xdf\xe5\x7b\x08\x9b\x4f\xb9\x3d\x84\x97\xe2\xf9\xa5\x2c\xf1\x71\x37\x87\xab\x6f\x20\x88\x94\x83\x4a\xe6\x5c\xe0\xf8\x17\x83\xa8\x3f\xde\xd0\xad\xe5\xcb\x12\x52\x2e\x2b\x11\x57\x26\x38\xa8\x5c\x08\x34\x35\x08\xf7\x05\x19\xf9\xc4\x14\x8b\xf2\x15\x60\x0c\xc4\x1d\xbe\x51\x64\x94\x08\xa8\x19\xcb\x97\x64\x0c\xf6\x71\x8c\x81\xc7\xb8\xbe\x93\xb3\xe0\x7c\xf4\x0a\x1e\xa7\xce\xf1\xae\x74\x75\xbb\x35\x12\x4a\xfa\x43\x8d\x33\x48\x47\xcf\x54\x6c\x93\x9b\x9e\xab\xce\x8a\xb3\xfe\x09\x00\x00\xff\xff\x6e\x05\x0e\x81\xd1\x11\x00\x00") +var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathPluginYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x6d\x6f\xdb\x36\x10\xfe\xee\x5f\x71\x48\x0a\xb4\x03\x2a\x2b\xe9\x1b\x52\x01\xfe\xb0\x26\xd9\x56\xac\x4d\x82\x25\xeb\x3e\x06\xb4\x78\xb6\x0e\xa1\x48\x81\x3c\x29\xf1\x7e\xfd\x70\x94\xed\x48\xb6\xe2\xb8\xc5\x06\xcc\x40\x81\x96\xbc\x37\xde\xdd\xf3\xdc\xa9\x87\x70\x8d\xbe\xa1\x1c\x41\xe3\x8c\x2c\x6a\x28\xd0\xe3\x6b\xa8\x4c\x1d\x20\xb4\x57\x17\xaa\x44\x98\xa2\x71\xf7\x40\x16\xae\x59\x31\xce\x6a\x73\x8d\xfc\x7a\x74\x08\xca\x23\x58\x44\x8d\x1a\x9c\x35\x0b\x98\x62\xae\xea\x80\xe0\x66\x90\x3b\xab\x89\xc9\x59\xc0\x87\xca\xa8\x68\x9d\xec\xe8\x10\x0a\xe6\x2a\x64\x69\x3a\x27\x2e\xea\xe9\x38\x77\x65\x7a\x57\x4f\xd1\x5b\x64\x0c\xdd\xbf\x52\x08\x35\x86\xf4\xc3\xc7\x0f\x47\x27\xa3\xd1\x1d\x59\x9d\xad\xe2\x1d\xa9\x8a\xbe\xa1\x0f\xe4\x6c\x06\xcd\xf1\xa8\x44\x56\x5a\xb1\xca\x46\x00\x56\x95\x98\x41\x1e\x28\x29\x5c\xe0\x4a\x71\x51\x99\x7a\x4e\x76\x04\x60\xd4\x14\x4d\x10\x21\x00\x55\x55\x83\x52\xa1\xc2\x5c\x24\x02\x1a\xcc\xd9\xf9\xdd\xd2\x00\x95\xf3\xbc\x34\x99\x2c\x7d\xeb\xba\x2c\x17\xf1\xa4\xbd\xce\xe0\xf8\xcd\xdb\x77\xef\x47\x49\x92\xac\x9e\xf1\x98\xc6\xde\x53\x54\x55\x85\x74\xdf\xf7\x3c\x46\xba\x2e\x54\x06\x07\xdb\x82\x07\x23\x80\x43\xb8\xb4\x08\x1e\x2b\x43\xb9\x8a\xb5\xca\xe2\xe9\x6f\x2e\x30\x88\x28\x68\x4f\x0d\xfa\xb6\x8c\xf7\xce\xdf\x05\xb8\x2f\xd0\x02\x36\xe8\x17\x5c\x90\x9d\x83\xaf\x6d\x88\x4a\xce\x82\x82\x40\x76\x6e\x10\xac\xd3\x38\x86\xbf\x10\x54\x5e\x10\x36\x08\x5c\x28\x86\xe9\x02\x02\x2b\xcf\xa2\x46\x0c\xce\xe6\x08\xca\x6a\xe0\x02\x6d\x34\x91\xbb\xc4\xb8\x5c\x31\x82\x32\x06\x1c\x17\xe8\xa1\x72\x3a\x40\x43\x0a\xc8\x32\xfa\xa4\x72\x1a\xd4\x6c\x46\x96\x58\x92\xb9\x8c\x3d\x64\x70\xbc\x55\x9d\x52\x71\x5e\x7c\xe9\x14\x77\x57\xc1\x18\xcb\xca\x28\xc6\xa5\x6a\x27\xd3\xf2\x33\x3d\x2b\xbb\xec\x00\xac\x0a\x20\xbf\xdc\x59\x96\x26\xf7\x1d\xdd\x55\x3f\x48\x8e\x92\x36\xbf\x89\xc7\x39\x05\xf6\xca\xaf\xa5\x00\xa8\x54\x73\xcc\xe0\xee\x24\x8c\xe7\xb9\x1f\x93\x4b\x03\xcd\x93\xc0\xce\xab\x39\xa6\xe2\x7c\xd0\x42\xd6\x1c\x8f\xdf\x8e\x8f\x3a\x86\x94\x9f\x77\xdc\xb7\x21\x24\x49\x33\x79\xbf\x75\x26\x46\x95\xd6\x1e\x43\x98\x88\x07\xf9\x33\x0e\x2e\xbf\xdb\x92\x14\x40\x1a\xe4\xb5\x5b\x81\x74\x22\x89\x98\xa4\x8d\xf2\xa9\xa1\x69\xba\x14\x49\xdb\xd4\x84\xb4\x9b\xae\x21\xc3\x01\xf3\xda\x13\x2f\x4e\x9d\x65\x7c\xe0\x7e\xc4\x87\x70\x53\x50\x00\x0a\x60\x31\xc7\x10\x94\x5f\xb4\x4d\x39\x73\x1e\xc2\x22\x30\x96\x01\xee\x89\x0b\xb8\x3e\xff\x42\xb6\x7e\x78\x2d\x8d\xea\x71\xc3\x88\x95\x28\x3d\x35\x64\x70\x8e\x1a\x02\x69\xcc\x95\xef\x94\x09\x72\x65\xad\x63\x50\xb9\x78\x81\xda\xd2\x03\x68\x57\x2a\xb2\x20\xe1\x22\x6f\x18\xcc\x3d\x2a\x46\x2d\xad\xdd\xb1\x7b\x7a\xfd\x79\x85\x9c\xb5\xe9\x71\x4f\xf3\x51\x38\x03\xf6\x75\x37\x4e\xb4\xcd\x66\xb5\xda\x86\xf9\xfd\xcf\x4f\xe7\xb7\x17\x97\x67\xe7\xb7\x17\x3f\x7f\x3d\xef\x89\x00\x34\xca\xd4\xf8\x8b\x77\x65\xb6\x71\x01\x30\x23\x34\xfa\x0f\x9c\x6d\xdf\x48\x23\xf7\x18\x73\x5b\x20\x2a\x5f\x29\x2e\xb2\xd8\xd8\x63\xe9\x39\xe1\x94\x8e\x68\xe3\x4c\x5d\xe2\x57\x57\x5b\xee\xf5\x59\x02\xa5\x9c\xb5\xca\x52\xf1\x9e\xf9\xf6\x4d\x6d\x52\x13\x4d\xfe\x49\xc5\x6e\x8b\x0d\x58\xe8\x75\xe0\x2e\x3b\xd2\x7f\x82\xe9\x0d\xa1\x2e\x95\xae\xaf\xb7\xc0\xba\x6a\xdc\xbd\xf1\xd9\x27\x06\x01\xe5\xbb\x67\x41\x79\x90\x2c\xd1\x2c\x3e\x27\x2b\x0b\x63\xc1\x8a\x78\x21\x77\xb0\xad\xd0\x4c\xde\x0f\x9c\xa2\xd5\x95\x23\xcb\x93\x17\xaf\x4e\xaf\x3f\xdf\x9e\x5f\x9c\x5d\x5d\x7e\xbe\xb8\xf9\x69\x40\x54\x0a\x4a\x7a\xf2\xe2\x55\xbf\xbd\x36\x44\x05\x7f\xd8\x22\x4e\xd3\x6c\x86\x1e\x85\xbc\xd9\xc1\xe0\xbc\x4e\x96\xdc\xb1\x22\x27\x79\x4a\x64\x87\x54\x63\x65\xdc\x62\xc3\x74\x02\xf7\x08\x85\x6a\x10\x14\x30\x06\x0e\xed\xb8\xc8\x0b\xcc\xef\x42\xe4\x49\x30\x54\x12\x87\xf1\x76\xf8\xa5\x7a\x68\xfb\x2f\x54\xe8\x45\x74\x72\x7c\x74\xb0\x0f\x9a\xba\x79\x19\xc2\x52\x16\xc1\x9f\xa5\xe9\x2e\x22\xfc\x7f\x03\x73\x27\xa3\xee\x60\xa0\xce\xf2\xb2\x7a\xe8\x9a\xc6\xae\xe2\xe6\xf2\xf1\xe4\xe3\xc9\x00\x86\x0a\x54\x86\x8b\xbf\x37\xfc\x38\x76\xb9\x33\x19\xdc\x9c\x5e\x75\x6e\x0c\x35\x68\x31\x84\x2b\xef\xa6\xd8\x0f\x6d\xa6\xc8\xd4\x1e\x6f\x0a\x8f\xa1\x70\x46\x67\xd0\x1f\x55\xb2\x2b\xfe\x8a\xbc\x99\xb6\xaa\xc5\xf9\x50\x10\xab\x8d\x6b\xe8\x4e\x56\x09\x52\xe6\x0c\x8d\x5a\x5c\xa3\x2c\xa8\xb2\x4d\x1c\xf5\x64\x98\x4a\x74\x35\xaf\xaf\xdf\xf6\x9f\x88\x9e\x9c\x5e\x5f\xbe\xd9\x83\x1b\x9f\x63\xc7\x9d\xfc\xb8\xa9\xbc\x35\x71\x9d\x0e\x1b\xd6\x5a\x71\xef\x2a\x35\x8f\x4c\x99\xc1\x27\xd2\xe4\x31\x97\x7f\x28\x33\xe8\x3b\xea\x44\x1a\xf9\x5e\xff\xed\xc4\xff\x17\x42\x58\x5a\x7a\xc6\xff\x93\xcc\x3e\xc8\xed\x4f\xdb\xd1\xd8\x0c\xaa\x6b\x6c\x7a\x9a\x2b\xdc\xaf\x5a\x38\xa9\xa4\x87\xff\xcb\x89\xb8\x7b\xd6\xac\xe2\x88\x61\xc8\xa8\x39\xde\x39\x6a\xf6\xdd\xf4\x44\xae\x05\x4c\x22\xe8\x99\x44\xd0\x8f\xba\x2f\xec\x6d\xb5\x42\xf2\xf1\x65\x7d\x6c\xec\x6c\x91\xde\x52\xd8\x47\xdc\xa2\xc2\x0c\xce\x62\x7f\x38\xbf\xb8\xf4\xa7\x71\xd3\x1a\xed\x91\xae\xef\x0d\x65\x13\x2d\xfb\xba\x7e\x02\x1f\x3f\x96\x89\xdb\xe5\x1e\xb3\xd8\x15\xca\x56\x08\x4f\x2e\x3f\x3f\x16\xc4\x77\xf9\x1e\xc2\xe6\x53\x6e\x0f\xe1\xa5\x78\x7e\x29\x0b\x7c\xdc\xcb\xe1\xea\x1b\x08\x22\xe5\xa0\x92\x39\x17\x38\xfe\x6f\x41\xd4\x1f\x6f\xe8\xd6\xf2\x55\x09\x29\x97\x95\x88\x2b\x13\x1c\x54\x2e\x04\x9a\x1a\x84\xfb\x82\x8c\x7c\x5e\x8a\x45\xf9\x02\x30\x06\xe2\xfe\xde\x28\x32\x4a\x04\xd4\x8c\xe5\x2b\x32\x06\xfb\x38\xc6\xc0\x63\x5c\xdd\xc9\x59\x70\x3e\x7a\x05\x8f\x53\xe7\x78\x57\xba\xba\xdd\x1a\x09\x25\xfd\xa1\xc6\x19\xa4\xa3\x67\x2a\xb6\xc9\x4d\xcf\x55\x67\xc5\x59\xff\x04\x00\x00\xff\xff\xb0\xb8\x68\x07\xcd\x11\x00\x00") func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathPluginYamlBytes() ([]byte, error) { return bindataRead( @@ -2485,7 +2485,7 @@ func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathPluginYaml() (* return a, nil } -var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathProvisionerYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x53\xc1\x6e\xeb\x36\x10\xbc\xeb\x2b\x16\xaf\xd7\xd2\xaa\xdb\xa6\x28\x04\xf8\x10\x24\x39\x04\x4d\xd3\x02\x0e\x7a\x5f\x53\x6b\x69\x61\x8a\x64\xc9\xa5\x62\xfd\x7d\x41\x59\x49\x24\x19\x4d\x5a\x1d\x97\x33\xc3\xd9\xe1\xe8\xc4\xb6\xae\x60\x4f\xa1\x67\x4d\x05\x7a\xfe\x8b\x42\x64\x67\x2b\xe8\xb7\x45\x47\x82\x35\x0a\x56\x05\x80\xc5\x8e\x2a\xd0\x91\x55\xeb\xa2\x78\x94\x56\xf9\xe0\x7a\xce\x60\x0a\x50\x00\x18\x3c\x90\x89\x19\x0b\x80\xde\x7f\x06\x8e\x9e\x74\x06\x46\x32\xa4\xc5\x85\xff\x44\x02\xf0\x2e\xc8\x74\x81\x9a\x0c\xd5\xa9\xeb\x86\x71\x72\x39\xae\x60\xfb\xe3\x4f\x3f\xdf\x14\x85\x52\xaa\x98\x96\x13\x14\x3a\x26\xb3\x27\x59\x2c\x88\xde\xc7\xf2\x7f\x6d\x39\xf3\x3d\xe6\xf5\x3c\xa2\xbf\xfd\x1b\xfc\x5b\x01\x10\xc8\x1b\xd6\x18\x2b\xd8\x5e\xed\xdb\xa1\xe8\xf6\x69\x96\xda\x17\x11\x14\x00\x42\x9d\x37\x28\x34\x09\xcc\x9c\xe7\xcf\x2c\xb4\xbe\x56\x03\x78\x5b\x68\x44\x1f\x8f\x6c\x59\x86\x0f\xbe\x77\xf5\xed\xd5\x30\xef\xf4\x77\xe2\x40\xf5\x7d\x0a\x6c\x9b\xbd\x6e\xa9\x4e\x86\x6d\xf3\xd8\x58\xf7\x3e\x7e\x38\x93\x4e\x92\x83\x9e\x31\xd5\xc5\xe2\x7e\x11\xc3\xc7\x37\x06\xf2\x70\xf6\x81\x62\xf6\x18\xd7\xe7\x0a\x4e\x34\x8c\x0f\xb7\x3a\x00\x70\x9e\x02\x66\x49\x78\xb4\x57\x87\x3d\x9a\x44\x57\x6a\x59\x6f\x1e\x8e\x37\xa9\xe1\x25\x59\x9c\x77\xc6\x35\xc3\x6f\xf9\xda\x53\x3a\x50\xb0\x24\x14\x37\xec\xca\xcc\xca\x6d\x99\xf0\x53\x23\x6e\xb5\x76\xc9\xca\xf3\x7b\x8d\xd6\x81\x03\x68\x67\x05\xd9\x52\x98\x19\x52\xb3\xe2\x5d\x33\xf2\xc7\x1d\x36\x54\x41\xa3\x43\xbe\xfc\xf4\x6b\x54\x51\xb0\x61\xdb\x28\x1d\xb9\x5c\xf1\xaa\x7e\xbb\xf9\x65\xf3\xc3\x8c\x8e\xa1\x59\xed\xaf\x40\xf5\xbb\x9b\xf5\x28\xab\x29\xac\xeb\xfc\x02\xbb\x72\x92\xde\x44\xa7\x4f\x57\xc8\x23\xa1\xa4\x40\xaa\x41\xa1\xb8\x7b\x99\x92\xda\x49\x48\x34\xc3\x46\xd2\x29\xb0\x0c\x77\xce\x0a\x9d\x65\xe9\xe1\x3b\x78\x69\x39\x02\x47\xb0\xa4\x29\x46\x0c\x03\x38\x6b\x06\x38\xba\x00\x71\x88\x42\x5d\x84\x57\x96\x16\xf6\x0f\x4f\x6c\xd3\xf9\x7b\x78\x6d\x29\xd0\x4a\xc4\x3a\xab\x7c\xe0\x9e\x0d\x35\x54\x43\xe4\x9a\x34\x86\x59\xd0\xa0\xd1\x5a\x27\x80\x3a\xdf\x02\xc9\xf2\x19\x6a\xd7\x21\x5b\xc8\xab\x91\xac\x04\x75\x20\x14\xaa\xe1\x30\xc0\x4c\xf7\x6e\xff\x08\x75\xe0\x9e\x66\xd2\x9b\x05\xf3\x03\x5c\xc1\x2a\x87\xde\x99\xd4\xd1\xef\xb9\x1c\x57\x0f\xd1\xe5\xe9\x9f\x28\x6d\x05\x39\xee\x55\x4d\x2f\xcd\xb8\xf8\x54\x35\xbf\x95\xe2\x22\xb8\xe8\x50\xae\xe4\x28\xb3\x34\x75\x11\xee\x31\x94\x86\x0f\x65\x6e\xb1\x21\x29\x2f\x6d\x8f\xe5\xfc\x0f\x58\x76\x7f\xf0\x54\xc1\x3d\x87\xf1\x57\x1d\xfe\x08\x77\x63\x2a\xc5\x27\xce\xfe\x09\x00\x00\xff\xff\xc1\xc6\x63\xa0\x4d\x06\x00\x00") +var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathProvisionerYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x53\xc1\x6e\xdb\x3a\x10\xbc\xeb\x2b\x16\x79\xd7\x47\xfb\xf9\xb5\x29\x0a\x01\x3e\x04\x49\x0e\x41\xd3\xb4\x80\x83\xde\xd7\xd4\x5a\x5a\x98\x22\x59\x72\xa9\x58\x7f\x5f\x50\x76\x12\x49\x46\x93\x96\x80\x2e\xe4\xcc\x70\x76\x38\xda\xb3\xad\x4a\xd8\x50\xe8\x58\x53\x81\x9e\x7f\x50\x88\xec\x6c\x09\xdd\xaa\x68\x49\xb0\x42\xc1\xb2\x00\xb0\xd8\x52\x09\x3a\xb2\x6a\x5c\x14\x8f\xd2\x28\x1f\x5c\xc7\x19\x4c\x01\x0a\x00\x83\x5b\x32\x31\x63\x01\xd0\xfb\xb7\xc0\xd1\x93\xce\xc0\x48\x86\xb4\xb8\xf0\x47\x24\x00\xef\x82\x9c\x2e\x50\x27\x43\x55\x6a\xdb\x7e\xd8\x39\x1e\x97\xb0\xfa\xff\xc3\xc7\xcb\xa2\x50\x4a\x15\xa7\xe1\x04\x85\x76\xc9\x6c\x48\x26\x03\xa2\xf7\x71\xf9\x57\x53\x8e\x7c\x0f\x79\x3d\x0c\xe8\x8b\xdf\xc1\x2f\x0a\x80\x40\xde\xb0\xc6\x58\xc2\xea\x6c\xde\x16\x45\x37\xf7\xa3\xd4\xde\x89\xa0\x00\x10\x6a\xbd\x41\xa1\x93\xc0\xc8\x79\x5e\x66\xa2\xf5\xbe\x1a\xc0\xf3\x40\x03\x7a\xb7\x63\xcb\xd2\xbf\xf2\xbd\xab\xae\xce\x36\xf3\x4c\x3f\x13\x07\xaa\x6e\x52\x60\x5b\x6f\x74\x43\x55\x32\x6c\xeb\xbb\xda\xba\x97\xed\xdb\x03\xe9\x24\x39\xe8\x11\x53\x1d\x2d\x6e\x26\x31\xbc\xae\x21\x90\xdb\x83\x0f\x14\xb3\xc7\x38\x3f\x57\xb0\xa7\x7e\x78\xb8\xd9\x01\x80\xf3\x14\x30\x4b\xc2\x9d\x3d\x3b\xec\xd0\x24\x3a\x53\xcb\x7a\xe3\x70\xbc\x49\x35\x4f\xc9\xe2\xbc\x33\xae\xee\xbf\xe4\x6b\xf7\x69\x4b\xc1\x92\x50\x5c\xb0\x5b\x66\x56\x6e\xcb\x09\x7f\x6a\xc4\x95\xd6\x2e\x59\x79\x78\xa9\xd1\x3c\x70\x00\xed\xac\x20\x5b\x0a\x23\x43\x6a\x54\xbc\x73\x46\x5e\xdc\x62\x4d\x25\xec\x3f\xc7\x45\xad\x43\x36\x10\xb9\x56\x51\x5c\xc0\x9a\x96\x33\x5e\xd9\xad\x16\x9f\x16\xff\x8d\xe8\x18\xea\xd9\xfc\x0a\x54\xb7\xbe\x9c\x6f\xa9\xac\x84\x55\x95\x5f\x60\x9d\x65\xf3\xb7\x88\x4e\xef\xcf\x90\x3b\x42\x49\x81\x54\x8d\x42\x71\xfd\x78\x4a\x6a\x2d\x21\xd1\x08\x1b\x49\xa7\xc0\xd2\x5f\x3b\x2b\x74\x90\xa9\x87\x7f\xe0\xb1\xe1\x08\x1c\xc1\x92\xa6\x18\x31\xf4\xe0\xac\xe9\x61\xe7\x02\xc4\x3e\x0a\xb5\x11\x9e\x58\x1a\xd8\xdc\xde\xb3\x4d\x87\x7f\xe1\xa9\xa1\x40\x33\x11\xeb\xac\xf2\x81\x3b\x36\x54\x53\x05\x91\x2b\xd2\x18\x46\x41\x83\x46\x6b\x9d\x00\xea\x7c\x0b\x24\xcb\x07\xa8\x5c\x8b\x6c\x21\x8f\x46\x32\x13\xd4\x81\x50\xa8\x82\x6d\x0f\x23\xdd\xeb\xcd\x1d\x54\x81\x3b\x1a\x49\x2f\x26\xcc\x57\x70\x09\xb3\x1c\x3a\x67\x52\x4b\x5f\x73\x39\xce\x1e\xa2\xcd\xbb\xdf\x51\x9a\x12\x72\xdc\xb3\x9a\x1e\x9b\x71\xf4\xa9\x2a\x7e\x2e\xc5\x51\x70\xd2\xa1\x5c\xc9\x41\x66\x6a\xea\x28\xdc\x61\x58\x1a\xde\x2e\x73\x8b\x0d\xc9\xf2\xd8\xf6\xb8\x1c\xff\x01\xd3\xee\xf7\x9e\x4a\xb8\xe1\x30\xfc\xaa\xfd\xb7\x70\x3d\xa4\x52\xbc\xe1\xec\x57\x00\x00\x00\xff\xff\x01\x46\xee\x3e\x4d\x06\x00\x00") func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathProvisionerYamlBytes() ([]byte, error) { return bindataRead( @@ -2505,7 +2505,7 @@ func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathProvisionerYaml return a, nil } -var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathResizerYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x53\xc1\x6e\xdb\x38\x10\xbd\xeb\x2b\x06\xd9\xeb\xd2\x4a\x76\x37\xc0\x42\x40\x0e\x41\x92\x43\xd0\x34\x2d\xe0\xa2\x77\x9a\x1c\x4b\x03\x53\x24\x4b\x0e\x15\xab\x5f\x5f\x50\x76\x62\x4a\x6e\xd3\xea\x48\xbe\x79\x7c\xef\xcd\xd3\x8e\xac\x6e\x60\x8d\x61\x20\x85\x95\xf4\xf4\x15\x43\x24\x67\x1b\x18\xae\xaa\x1e\x59\x6a\xc9\xb2\xa9\x00\xac\xec\xb1\x01\x15\x49\x74\x2e\xb2\x97\xdc\x89\x80\x91\xbe\x63\xa8\x00\x8c\xdc\xa0\x89\x19\x06\x20\xbd\xff\x05\x2e\x7a\x54\x19\x13\xd1\xa0\x62\x17\x7e\x87\x07\xf0\x2e\xf0\x91\x56\x1c\x15\xe8\xd4\xf7\xe3\x74\x72\xb8\x6e\xe0\xea\x9f\x7f\xff\xbb\xae\x2a\x21\x44\x75\x74\xc3\x92\x71\x9b\xcc\x1a\x79\xe6\x48\x7a\x1f\xeb\x3f\xb7\x75\x92\x3b\x85\xf3\x3c\x21\x2f\x7e\x06\xbd\xa8\x00\x02\x7a\x43\x4a\xc6\x06\xae\xce\x2c\xf6\x92\x55\xf7\x54\x64\xf4\xbe\x6b\xc6\xde\x1b\xc9\x78\x1c\x2e\xd4\xe6\xcf\xcc\x78\xde\x67\x02\x78\x35\x31\x21\xb7\x5b\xb2\xc4\xe3\x69\xd6\x3b\x7d\x7b\x76\x98\xbd\x7c\x4b\x14\x50\xdf\xa7\x40\xb6\x5d\xab\x0e\x75\x32\x64\xdb\xc7\xd6\xba\xb7\xe3\x87\x3d\xaa\xc4\x39\xd8\x62\x52\x1c\xe4\xad\x67\xf6\x4f\xdf\x14\xc4\xc3\xde\x07\x8c\x79\x25\x71\x79\x2f\x60\x87\xe3\xb4\xa8\xc5\x05\x80\xf3\x18\x64\xa6\x84\x47\x7b\x76\x39\x48\x93\xf0\x8c\x2d\xf3\x95\xc1\x78\x93\x5a\x9a\x0f\xb3\xf3\xce\xb8\x76\xfc\x90\x9f\xdd\xa5\x0d\x06\x8b\x8c\x71\x45\xae\xce\x53\xb9\x1d\x47\xfc\xb1\x05\xb7\x4a\xb9\x64\xf9\xf9\xad\x36\x65\xd8\x00\xca\x59\x96\x64\x31\x14\x62\x44\x51\xb2\x39\x3a\x7f\xd4\xcb\x16\x1b\x68\x55\xc8\x8f\xee\xfe\x8f\x22\xb2\x6c\xc9\xb6\x42\x45\xaa\x8b\x99\x66\xb8\x5c\x5d\xaf\x2e\x8b\x51\x19\xda\x85\x67\x01\x62\xb8\xb9\x5e\x1e\x65\x12\xa9\x75\x0e\xfd\xa6\x3e\xb2\xae\xa2\x53\xbb\x02\x18\x51\xa5\x40\x3c\xde\x39\xcb\xb8\xe7\x39\xed\x5f\xf0\xa5\xa3\x08\x14\xc1\xa2\xc2\x18\x65\x18\xc1\x59\x33\xc2\xd6\x05\x88\x63\x64\xec\x23\xbc\x10\x77\xb0\x7e\x78\x22\x9b\xf6\x7f\xc3\x4b\x87\x01\x17\x24\xd6\x59\xe1\x03\x0d\x64\xb0\x45\x0d\x91\x34\x2a\x19\x8a\xcc\x40\x49\x6b\x1d\x83\x54\xf9\x15\x48\x96\xf6\xa0\x5d\x2f\xc9\x42\x96\x8b\xbc\x20\x54\x01\x25\xa3\x86\xcd\x08\x05\xef\xdd\xfa\x11\x74\xa0\x01\x0b\xea\xd5\x6c\xf2\x04\x6e\x80\x43\x2a\x75\x0e\xce\xa4\x1e\x3f\xe6\x1d\x9f\x65\xdb\xe7\xd3\xcf\x92\xbb\x06\x72\x84\x8b\xb6\x1d\x96\x7c\xd0\x29\x34\xbd\xee\xf8\x40\x38\xab\x43\x6e\xd6\x44\x33\x17\x75\x20\x1e\x64\xa8\x0d\x6d\xea\x5c\x46\x83\x5c\x1f\x4a\x1b\xeb\xb2\xc8\xf3\x0a\x8f\x1e\x1b\xb8\xa7\x30\xfd\x71\xe3\xa7\x70\x37\xa5\x52\xbd\xa3\xec\x47\x00\x00\x00\xff\xff\xaa\x36\x3e\xc1\xf5\x05\x00\x00") +var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathResizerYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x53\xc1\x6e\xdb\x38\x10\xbd\xeb\x2b\x06\xd9\xeb\xca\x4e\x76\x37\xc0\x42\x40\x0e\x41\x92\x43\xd0\x34\x2d\xe0\xa2\x77\x9a\x1c\x4b\x03\x53\x24\x3b\x1c\x2a\x56\xbf\xbe\xa0\xec\xc4\x94\xdd\xa6\x25\xa0\xcb\xf0\xcd\xe3\x9b\x37\x4f\x5b\x72\xa6\x81\x15\xf2\x40\x1a\x2b\x15\xe8\x2b\x72\x24\xef\x1a\x18\xae\xaa\x1e\x45\x19\x25\xaa\xa9\x00\x9c\xea\xb1\x01\x1d\xa9\xee\x7c\x94\xa0\xa4\xab\x19\x23\x7d\x47\xae\x00\xac\x5a\xa3\x8d\x19\x06\xa0\x42\xf8\x05\x2e\x06\xd4\x19\x13\xd1\xa2\x16\xcf\xbf\xc3\x03\x04\xcf\x72\xa0\xad\x0f\x0a\x4c\xea\xfb\x71\xaa\xec\xaf\x1b\xb8\xfa\xe7\xdf\xff\xae\xab\xaa\xae\xeb\xea\x30\x8d\x28\xc1\x4d\xb2\x2b\x94\xd9\x44\x2a\x84\xb8\xfc\xf3\xb1\x8e\x72\x27\x73\x9e\x27\xe4\xc5\xcf\xa0\x17\x15\x00\x63\xb0\xa4\x55\x6c\xe0\xea\x6c\xc4\x5e\x89\xee\x9e\x0a\x8f\xde\x9f\x5a\xb0\x0f\x56\x09\x1e\x9a\x0b\xb5\xf9\xd8\x19\xcf\xfb\x4c\x00\xaf\x43\x4c\xc8\xcd\x86\x1c\xc9\x78\xec\x0d\xde\xdc\x9e\x15\xf3\x2c\xdf\x12\x31\x9a\xfb\xc4\xe4\xda\x95\xee\xd0\x24\x4b\xae\x7d\x6c\x9d\x7f\x2b\x3f\xec\x50\x27\xc9\xc6\x16\x9d\xf5\x5e\xde\x6a\x36\xfe\xf1\x4c\x46\x3c\xec\x02\x63\xcc\x2b\x89\xa7\xf7\x35\x6c\x71\x9c\x16\x75\x72\x01\xe0\x03\xb2\xca\x94\xf0\xe8\xce\x2e\x07\x65\x13\x9e\xb1\x65\xbe\xd2\x98\x60\x53\x4b\xf3\x66\xf1\xc1\x5b\xdf\x8e\x1f\xf2\xb3\xdb\xb4\x46\x76\x28\x18\x17\xe4\x97\xb9\x2b\xa7\xe3\x80\x3f\xa4\xe0\x56\x6b\x9f\x9c\x3c\xbf\xc5\xa6\x34\x1b\x40\x7b\x27\x8a\x1c\x72\x21\xa6\x2e\x42\x36\x47\xe7\x43\xbd\x6a\xb1\x81\xed\xff\x71\xd1\x6a\xce\x0f\x47\x6a\xeb\x28\x9e\x55\x8b\xcb\xa2\xa7\x19\x2e\x17\xd7\x8b\xcb\xa2\x55\x71\x7b\x32\x73\x0d\xf5\x70\x73\x7d\x5a\xca\x24\xca\x98\x6c\xfa\x4d\x66\xcc\xdf\x22\x7a\xbd\x2d\x80\x11\x75\x62\x92\xf1\xce\x3b\xc1\x9d\xcc\x69\xff\x82\x2f\x1d\x45\xa0\x08\x0e\x35\xc6\xa8\x78\x04\xef\xec\x08\x1b\xcf\x10\xc7\x28\xd8\x47\x78\x21\xe9\x60\xf5\xf0\x44\x2e\xed\xfe\x86\x97\x0e\x19\x4f\x48\x9c\x77\x75\x60\x1a\xc8\x62\x8b\x06\x22\x19\xd4\x8a\x0b\xcf\x40\x2b\xe7\xbc\x80\xd2\xf9\x15\x48\x8e\x76\x60\x7c\xaf\xc8\x41\x96\x8b\x72\x42\xa8\x19\x95\xa0\x81\xf5\x08\x05\xef\xdd\xea\x11\x0c\xd3\x80\x05\xf5\x62\xd6\x79\x04\x37\x20\x9c\x4a\x9d\x83\xb7\xa9\xc7\x8f\x79\xc7\x67\xde\xf6\xb9\xfa\x59\x49\xd7\x40\xb6\xf0\x24\x6d\xfb\x25\xef\x75\xd6\x86\x5e\x77\xbc\x27\x9c\xc5\x21\x27\x6b\xa2\x99\x8b\xda\x13\x0f\x8a\x97\x96\xd6\xcb\x1c\x46\x8b\xb2\xdc\x87\x36\x2e\xcb\x20\xcf\x23\x3c\x06\x6c\xe0\x9e\x78\xfa\xe3\xc6\x4f\x7c\x37\xb9\x52\xbd\xa3\xec\x47\x00\x00\x00\xff\xff\xb7\x8c\xb0\xd9\xf5\x05\x00\x00") func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathResizerYamlBytes() ([]byte, error) { return bindataRead( @@ -2525,7 +2525,7 @@ func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathResizerYaml() ( return a, nil } -var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathSnapshotterYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x53\x4d\x6f\xeb\x36\x10\xbc\xeb\x57\x2c\xd2\x6b\x69\xd5\x69\x03\x14\x02\x72\x08\x92\x1c\x82\xa6\x1f\x80\x8b\xde\xd7\xd4\x5a\x5a\x98\x22\x59\x72\xa9\x58\xff\xfe\x81\x92\xf3\x2c\xc9\x78\xc9\x7b\x3a\x92\x33\xc3\xd9\xd9\xd1\x91\x6d\x5d\xc1\x8e\x42\xcf\x9a\x0a\xf4\xfc\x1f\x85\xc8\xce\x56\xd0\x6f\x8b\x8e\x04\x6b\x14\xac\x0a\x00\x8b\x1d\x55\xa0\x23\xab\xd6\x45\xf1\x28\xad\x8a\x16\x7d\x6c\x9d\x08\x85\x02\xc0\xe0\x9e\x4c\xcc\x50\x00\xf4\xfe\x03\x6c\xf4\xa4\x33\x2e\x92\x21\x2d\x2e\x7c\x0f\x07\xc0\xbb\x20\x67\x79\x75\x76\x53\xa7\xae\x1b\xc6\x93\xe9\xba\x82\xed\xed\xaf\xbf\xdd\x15\x85\x52\xaa\x38\x4f\x26\x28\x74\x48\x66\x47\xb2\x98\x0e\xbd\x8f\xe5\x8f\x8d\x78\xb1\x3d\x86\xf5\xd7\x88\xbe\xf9\x16\xfc\xa6\x00\x08\xe4\x0d\x6b\x8c\x15\x6c\xaf\xc6\xed\x50\x74\xfb\x3a\xcb\xec\xf3\x04\x84\x3a\x6f\x50\xe8\x2c\x30\x73\x9e\x3f\xb3\xd0\xfa\x5c\x0d\xe0\x7d\xa0\x11\x7d\x38\xb0\x65\x19\x2e\x7c\xef\xea\x87\xab\xc3\x3c\xd3\xff\x89\x03\xd5\x4f\x29\xb0\x6d\x76\xba\xa5\x3a\x19\xb6\xcd\x4b\x63\xdd\xd7\xe3\xe7\x13\xe9\x24\x39\xe8\x19\x53\x4d\x16\x77\x8b\x18\x2e\xdf\x18\xc8\xf3\xc9\x07\x8a\x79\x45\x71\x7d\xaf\xe0\x48\xc3\xb8\xb8\xd5\x05\x80\xf3\x14\x30\x4b\xc2\x8b\xbd\xba\xec\xd1\x24\xba\x52\xcb\x7a\xf3\x70\xbc\x49\x0d\x2f\xc9\xe2\xbc\x33\xae\x19\xfe\xc8\xcf\x1e\xd3\x9e\x82\x25\xa1\xb8\x61\x57\x66\x56\x6e\xcb\x19\x7f\x6e\xc4\x83\xd6\x2e\x59\x99\x52\x5f\x87\x0d\xa0\x9d\x15\x64\x4b\x61\x66\x46\xcd\x4a\x77\xcd\xc8\x1f\x77\xd8\x50\x05\x8d\x0e\xf9\xe1\xe3\xef\x51\x45\xc1\x86\x6d\xa3\x74\xe4\x72\xc5\xab\xfa\xdb\xcd\x76\xf3\xcb\x8c\x8e\xa1\x59\xcd\xae\x40\xf5\xf7\x77\xeb\xa3\xac\xa6\xb0\xae\x73\xfa\xf7\xe5\x59\x7a\x13\x9d\x3e\xce\x90\x91\x74\x0a\x2c\xc3\xa3\xb3\x42\x27\x59\xea\xfe\x04\xff\xb6\x1c\x81\x23\x58\xd2\x14\x23\x86\x01\x9c\x35\x03\x1c\x5c\x80\x38\x44\xa1\x2e\xc2\x1b\x4b\x0b\xbb\xe7\x57\xb6\xe9\xf4\x33\xbc\xb5\x14\x68\x25\x62\x9d\x55\x3e\x70\xcf\x86\x1a\xaa\x21\x72\x4d\x1a\xc3\x2c\x3c\xd0\x68\xad\x13\x40\x9d\x5f\x81\x64\xf9\x04\xb5\xeb\x90\x2d\x64\xbb\x24\x2b\x41\x1d\x08\x85\x6a\xd8\x0f\x30\xd3\x7d\xdc\xbd\x40\x1d\xb8\xa7\x99\xf4\x66\xc1\xbc\x80\x2b\x90\x90\xe6\x3e\x7b\x67\x52\x47\x7f\xe6\x65\x5f\x85\xdb\xe5\xd3\x7f\x50\xda\x0a\x72\x84\xab\xda\x4d\xdb\x9e\x7c\xaa\x9a\xdf\x17\x3d\x09\x2e\x7a\x91\x2b\x36\xca\x2c\x4d\x4d\xc2\x3d\x86\xd2\xf0\xbe\xcc\xad\x34\x24\xe5\xd4\xde\x58\xce\x1b\xbd\xec\xf2\xe0\xa9\x82\x27\x0e\xe3\xaf\x37\xfc\x1d\x1e\xc7\x54\x8a\x0f\x9c\x7d\x09\x00\x00\xff\xff\x02\xff\x58\xad\x1a\x06\x00\x00") +var _testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathSnapshotterYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x53\x4d\x6f\xdb\x38\x10\xbd\xeb\x57\x0c\xb2\xd7\xa5\xbd\xce\x6e\x80\x85\x80\x1c\x82\x24\x87\xa0\xe9\x07\xe0\xa2\xf7\x31\x35\x96\x06\xa6\x48\x96\x1c\x2a\xd6\xbf\x2f\x28\x39\xb5\x24\xa3\x49\x4b\x40\x97\xe1\xbc\xc7\x37\x6f\x9e\x0e\x6c\xab\x12\xb6\x14\x3a\xd6\x54\xa0\xe7\x6f\x14\x22\x3b\x5b\x42\xb7\x29\x5a\x12\xac\x50\xb0\x2c\x00\x2c\xb6\x54\x82\x8e\xac\x1a\x17\xc5\xa3\x34\x2a\x5a\xf4\xb1\x71\x22\x14\x0a\x00\x83\x3b\x32\x31\xb7\x02\xa0\xf7\x6f\xf4\x46\x4f\x3a\xf7\x45\x32\xa4\xc5\x85\xdf\xc1\x00\x78\x17\xe4\x44\xaf\x4e\x6a\xaa\xd4\xb6\xfd\x50\x19\xaf\x4b\xd8\x5c\xff\xfb\xdf\x4d\x51\x28\xa5\x8a\xd3\x64\x82\x42\xfb\x64\xb6\x24\xb3\xe9\xd0\xfb\xb8\xfe\xb3\x11\xcf\xb2\x07\xb3\x3e\x0d\xdd\x57\xbf\x6a\xbf\x2a\x00\x02\x79\xc3\x1a\x63\x09\x9b\x8b\x71\x5b\x14\xdd\x3c\x4f\x3c\x7b\xdf\x01\xa1\xd6\x1b\x14\x3a\x11\x4c\x94\xe7\x63\x66\x5c\xef\xb3\x01\xbc\x0e\x34\x74\xef\xf7\x6c\x59\xfa\x33\xde\xbb\xea\xee\xa2\x98\x67\xfa\x9e\x38\x50\xf5\x90\x02\xdb\x7a\xab\x1b\xaa\x92\x61\x5b\x3f\xd5\xd6\xfd\x2c\x3f\x1e\x49\x27\xc9\x46\x4f\x90\x6a\x94\xb8\x9d\xd9\x70\x3e\x83\x21\x8f\x47\x1f\x28\xe6\x15\xc5\xe5\xbd\x82\x03\xf5\xc3\xe2\x16\x17\x00\xce\x53\xc0\x4c\x09\x4f\xf6\xe2\xb2\x43\x93\xe8\x82\x2d\xf3\x4d\xcd\xf1\x26\xd5\x3c\x07\x8b\xf3\xce\xb8\xba\xff\x90\x9f\x3d\xa4\x1d\x05\x4b\x42\x71\xc5\x6e\x9d\x51\x39\x2d\xa7\xfe\x53\x22\xee\xb4\x76\xc9\xca\xe8\xfa\xd2\x6c\x00\xed\xac\x20\x5b\x0a\x13\x31\x6a\x12\xba\x4b\x44\x3e\xdc\x62\x4d\x25\x1c\xfe\x8f\xab\x5a\x87\xfc\x78\xe4\x5a\x45\x71\x01\x6b\x5a\x2f\x70\x65\x77\xbd\xda\xac\xfe\x99\xc0\x31\xd4\x8b\xd9\x15\xa8\xee\xf6\x66\x59\x52\x99\x09\xab\x2a\xbb\x7f\x9b\x69\xf3\xb7\x8a\x4e\x1f\x26\x9d\x91\x74\x0a\x2c\xfd\xbd\xb3\x42\x47\x99\xf3\xfe\x05\x5f\x1b\x8e\xc0\x11\x2c\x69\x8a\x11\x43\x0f\xce\x9a\x1e\xf6\x2e\x40\xec\xa3\x50\x1b\xe1\x85\xa5\x81\xed\xe3\x33\xdb\x74\xfc\x1b\x5e\x1a\x0a\xb4\x20\xb1\xce\x2a\x1f\xb8\x63\x43\x35\x55\x10\xb9\x22\x8d\x61\x62\x1e\x68\xb4\xd6\x09\xa0\xce\xaf\x40\xb2\x7c\x84\xca\xb5\xc8\x16\xb2\x5c\x92\x05\xa1\x0e\x84\x42\x15\xec\x7a\x98\xf0\xde\x6f\x9f\xa0\x0a\xdc\xd1\x84\x7a\x35\x43\x9e\x9b\x4b\x90\x90\xa6\x3a\x3b\x67\x52\x4b\x1f\xf3\xb2\x2f\xcc\x6d\x73\xf5\x0b\x4a\x53\x42\xb6\x70\x11\xbb\x71\xdb\xa3\x4e\x55\xf1\xeb\xa2\x47\xc2\x59\x2e\x72\xc4\x06\x9a\xb9\xa8\x91\xb8\xc3\xb0\x36\xbc\x5b\xe7\x54\x1a\x92\xf5\x98\xde\xb8\x9e\x26\x7a\x9e\xe5\xde\x53\x09\x0f\x1c\x86\x5f\xaf\xff\x1c\xee\x07\x57\x8a\x37\x94\xfd\x08\x00\x00\xff\xff\x1c\xac\x57\x2e\x1a\x06\x00\x00") func testE2eTestingManifestsStorageCsiHostpathHostpathCsiHostpathSnapshotterYamlBytes() ([]byte, error) { return bindataRead( @@ -2585,7 +2585,7 @@ func testE2eTestingManifestsStorageCsiHostpathUsageCsiStorageclassYaml() (*asset return a, nil } -var _testE2eTestingManifestsStorageCsiMockCsiMockDriverAttacherYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x92\xcf\x8a\x1b\x31\x0c\xc6\xef\xf3\x14\x3a\xf4\xd0\x1e\x9c\xd9\xa5\x14\x8a\x61\x0f\xcb\xa6\xb7\xfe\xa3\x81\xde\x15\x8f\x3a\x11\xf1\xd8\x46\xd6\x98\xe6\xed\xcb\xc4\x59\x6a\xef\x52\xaa\x93\x91\xe5\x9f\x3e\x7d\xd6\x99\xc3\x64\xe1\xa0\xa8\xf4\x6b\xf5\x07\xd2\x01\x13\xff\x24\xc9\x1c\x83\x05\x4c\x29\x8f\xe5\x7e\x58\x48\x71\x42\x45\x3b\x00\x04\x5c\xc8\x82\xcb\x6c\x96\xe8\xce\xc9\xaf\x33\x07\x83\xaa\xe8\x4e\x24\x43\x4e\xe4\xb6\xaa\x4c\x9e\x9c\x46\xd9\xce\x00\x0b\xaa\x3b\x7d\xc6\x23\xf9\x5c\x13\xb0\xa1\xff\x4d\x01\x10\x4a\x9e\x1d\x66\x0b\xf7\x03\x80\xd2\x92\x3c\x2a\xdd\x68\x8d\x9a\x2d\x7c\x07\xfe\x2f\x1a\xe0\x59\xe4\xf5\x4c\x52\xd8\xd1\xa3\x73\x71\x0d\xfa\xb5\x1b\xee\x56\xe2\x62\x50\xe4\x40\xd2\xf4\x30\x8d\x0f\x1d\xbb\x06\x2f\x38\x93\x85\xd9\xc9\x8e\xe3\x78\xfe\x98\x4d\x56\x9c\x39\xcc\xc6\x65\x1e\xdb\x47\xb6\xbc\xdf\xdd\xed\xee\x8c\xb8\xfb\xe6\x3d\xca\xdc\x34\xab\x0d\x8d\x29\x0f\x1f\x5e\xe5\xae\xac\x69\x12\xca\xf9\xe1\xcd\xdb\xc7\xfd\xfe\xc7\xa7\xc3\xe1\x5d\x53\x46\xa1\xbc\x24\x55\xe9\xb7\xda\xee\x0e\xa0\xa0\x5f\xc9\xc2\x78\xd3\xb9\xcb\x7f\x7d\xa8\x76\xb9\x55\x58\x2f\x4f\x31\x28\xfd\xd6\x9e\x9c\x84\x0b\x7b\x9a\x69\xb2\xa0\xb2\x52\x73\x59\xa2\x5f\x17\xfa\xb2\x79\xdc\x0d\x66\x60\xd9\x72\xdf\x51\x4f\xb5\x69\x07\xac\x42\x37\x09\xa4\x66\xe2\x67\x87\x2b\xac\xfb\x8d\x53\xcc\x15\xd2\x0b\xaa\xd8\x82\x32\x7a\x3e\x8e\xe7\xf5\x48\x9e\x74\xac\x3b\x91\xc7\x17\xff\x5c\x43\x2f\x89\x2c\xec\x59\xae\xfb\x7b\xf9\x26\x4f\x42\xa8\xed\x2c\xaf\x54\x0d\x7f\x02\x00\x00\xff\xff\x0a\xed\x8d\xbc\x46\x03\x00\x00") +var _testE2eTestingManifestsStorageCsiMockCsiMockDriverAttacherYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x92\xcf\x8a\x1b\x31\x0c\xc6\xef\xf3\x14\x3a\xf4\xd0\x1e\x26\xd3\x5d\x28\x14\xc3\x1e\x96\x4d\x6f\xfd\x47\x03\xbd\x2b\x1e\x75\x22\xe2\xb1\x8d\xac\x31\xcd\xdb\x17\xc7\x59\x6a\xef\x52\x2a\x30\x18\x59\xfe\xe9\xd3\x67\x9f\xd9\xcf\x06\x0e\x8a\x4a\xbf\x36\x77\x20\x1d\x30\xf2\x4f\x92\xc4\xc1\x1b\xc0\x18\xd3\x94\xef\x86\x95\x14\x67\x54\x34\x03\x80\xc7\x95\x0c\xd8\xc4\xe3\x1a\xec\x39\xba\x6d\x61\x3f\xa2\x2a\xda\x13\xc9\x90\x22\xd9\x52\x95\xc8\x91\xd5\x20\x65\x0f\xb0\xa2\xda\xd3\x67\x3c\x92\x4b\x35\x01\x05\xfd\x6f\x0a\x80\x50\x74\x6c\x31\x19\xb8\x1b\x00\x94\xd6\xe8\x50\xe9\x46\x6b\xd4\x94\x70\x1d\xf8\xbf\x68\x80\x67\x91\xd7\x3d\x49\x66\x4b\x8f\xd6\x86\xcd\xeb\xd7\x6e\xb8\x5b\x89\x0d\x5e\x91\x3d\x49\xd3\x63\x6c\x7c\xe8\xd8\x35\x78\xc5\x85\x0c\x9c\x3f\xa6\xdd\x62\x65\xc7\x61\x4a\xbc\x8c\x49\x83\xe0\x42\x53\x7b\xc9\xe4\xfb\xdd\xfd\xee\x7d\x73\x17\x65\x69\x1a\xd5\x66\xe3\x98\x1f\x3e\xbc\xca\x5d\x39\xf3\x2c\x94\xd2\xc3\x9b\xb7\x8f\xfb\xfd\x8f\x4f\x87\xc3\xbb\xa6\x8c\x7c\x7e\x49\xaa\xb2\x6f\xb5\xdd\x19\x40\x46\xb7\x91\x81\xa2\xaf\xac\x5d\xfa\xeb\x41\xb5\xca\x6e\xc2\x7a\x79\x0a\x5e\xe9\xb7\xf6\xe4\x28\x9c\xd9\xd1\x42\xb3\x01\x95\x8d\x9a\xc3\x1c\xdc\xb6\xd2\x97\xe2\x6f\x37\xd8\x08\x6b\xc9\x7d\x47\x3d\xd5\xa6\x1d\xb0\x0a\x2d\x12\x48\xc7\x99\x9f\xdd\xad\xb0\xee\x25\x4e\x21\x55\x48\x2f\xa8\x62\x33\xca\xe4\xf8\x38\x9d\xb7\x23\x39\xd2\xa9\xfe\x87\x34\xbd\x78\xe3\x1a\x7a\x89\x64\x60\xcf\x72\xfd\xbb\x97\x6f\xf2\x24\x84\xda\xce\xf2\x4a\xd5\xf0\x27\x00\x00\xff\xff\x92\x6d\x20\x00\x42\x03\x00\x00") func testE2eTestingManifestsStorageCsiMockCsiMockDriverAttacherYamlBytes() ([]byte, error) { return bindataRead( @@ -2605,7 +2605,7 @@ func testE2eTestingManifestsStorageCsiMockCsiMockDriverAttacherYaml() (*asset, e return a, nil } -var _testE2eTestingManifestsStorageCsiMockCsiMockDriverResizerYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x92\xcf\x6a\x1c\x31\x0c\xc6\xef\xf3\x14\x22\xf4\xd0\x1e\xbc\x93\x40\x0b\xc5\x90\x43\xc8\xf6\xd6\x7f\x74\xa1\x77\xad\x47\x9d\x15\xeb\xb1\x8d\xac\x31\xdd\x3e\x7d\x99\x78\x42\x3d\x59\x4a\x74\x32\xb2\xfc\xd3\xa7\xcf\x3a\x73\x18\x2c\x1c\x14\x95\x7e\xcd\xfe\x40\xda\x61\xe2\x9f\x24\x99\x63\xb0\x80\x29\xe5\xbe\xdc\x75\x13\x29\x0e\xa8\x68\x3b\x80\x80\x13\x59\x70\x99\xcd\x14\xdd\x39\xf9\x79\xe4\x60\x84\x32\xff\x21\xe9\x72\x22\xb7\x14\x65\xf2\xe4\x34\xca\x72\x06\x98\x50\xdd\xe9\x33\x1e\xc9\xe7\x9a\x80\x85\xfc\x5f\x08\x80\x50\xf2\xec\x30\x5b\xb8\xeb\x00\x94\xa6\xe4\x51\x69\x85\x35\x5a\x96\xf0\x1b\xee\x6b\x64\x80\x67\x89\x4f\x67\x92\xc2\x8e\x1e\x9c\x8b\x73\xd0\xaf\x9b\xc9\xd6\x12\x17\x83\x22\x07\x92\xa6\x85\x69\x4c\x68\xd1\x35\x78\xc2\x91\x2c\x8c\x4e\x76\x1c\xfb\xf3\xc7\x6c\xb2\xe2\xc8\x61\x34\x2e\x73\xdf\xbc\xb1\xe5\x76\xf7\x7e\x77\xdb\x3c\x45\x19\x9b\x36\xb5\xd5\x8d\x31\xe5\xfe\xc3\xcd\x75\x76\x21\xe1\x30\x08\xe5\x7c\xff\xe6\xed\xc3\x7e\xff\xe3\xd3\xe1\xf0\xae\x2d\xa4\x50\x5e\xd2\xaa\xf0\xb5\x78\x73\x07\x50\xd0\xcf\x64\xa1\x5f\x65\xee\xf2\x3f\x17\xaa\x59\x6e\x16\xd6\xcb\x63\x0c\x4a\xbf\x75\x4b\x4e\xc2\x85\x3d\x8d\x34\x58\x50\x99\xa9\xb9\x2c\xd1\xcf\x13\x7d\x59\x1c\xde\x0c\x67\x60\x5a\x72\xdf\x51\x4f\xb5\xe9\x06\x58\x85\x2e\x12\x48\xcd\xc0\xcf\x06\x57\xd8\xe6\x2f\x4e\x31\x57\xc8\x56\x50\xc5\x16\x94\xde\xf3\xb1\x3f\xcf\x47\xf2\xa4\x7d\x5d\x88\xdc\xbf\xf8\xe5\x1a\x7a\x49\x64\x61\xcf\xf2\xb4\xbb\x97\x6f\xf2\x28\x84\xda\xce\x72\xa5\xea\x6f\x00\x00\x00\xff\xff\x9b\x6d\x04\x75\x40\x03\x00\x00") +var _testE2eTestingManifestsStorageCsiMockCsiMockDriverResizerYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x92\xcf\x6a\x1c\x31\x0c\xc6\xef\xf3\x14\x22\xf4\xd0\x1e\x66\x26\x39\x04\x8a\x21\x87\x90\xed\xad\xff\xe8\x42\xef\x5a\x8f\x3a\x2b\xd6\x63\x1b\x59\x63\xba\x7d\xfa\xe2\x78\x43\x3d\x59\x4a\x04\x06\x23\xcb\x3f\x7d\xfa\xec\x13\xfb\xc9\xc0\x5e\x51\xe9\xd7\xea\xf6\xa4\x1d\x46\xfe\x49\x92\x38\x78\x03\x18\x63\x1a\xf3\x5d\xb7\x90\xe2\x84\x8a\xa6\x03\xf0\xb8\x90\x01\x9b\xb8\x5f\x82\x3d\x45\xb7\xce\xec\x7b\xa1\xc4\x7f\x48\xba\x14\xc9\x96\xa2\x44\x8e\xac\x06\x29\x7b\x80\x05\xd5\x1e\x3f\xe3\x81\x5c\xaa\x09\x28\xe4\xff\x42\x00\x84\xa2\x63\x8b\xc9\xc0\x5d\x07\xa0\xb4\x44\x87\x4a\x17\x58\xa3\xa5\x84\xdb\x70\xdf\x22\x03\xbc\x48\x7c\xde\x93\x64\xb6\xf4\x68\x6d\x58\xbd\x7e\xdd\x4c\x76\x29\xb1\xc1\x2b\xb2\x27\x69\x5a\xf4\x8d\x09\x2d\xba\x06\x2f\x38\x93\x81\xd3\xc7\x34\xcc\x56\x06\x0e\x63\xe2\xb9\x4f\x1a\x04\x67\x1a\x9b\x3b\x26\xdf\x0e\xf7\xc3\x6d\x73\x15\x65\x6e\xda\xd4\x56\x37\x7d\x9f\x1f\xee\x6f\xae\xb3\x85\x84\xd3\x24\x94\xd2\xc3\xbb\xf7\x8f\xbb\xdd\x8f\x4f\xfb\xfd\x87\xb6\x90\x7c\x7e\x4d\xab\xc2\x2f\xc5\x9b\x33\x80\x8c\x6e\x25\x03\x45\x62\x59\x43\xfa\xe7\x42\x35\xcb\xae\xc2\x7a\x7e\x0a\x5e\xe9\xb7\x6e\xc9\x51\x38\xb3\xa3\x99\x26\x03\x2a\x2b\x35\x87\x39\xb8\x75\xa1\x2f\xc5\xe1\xcd\x70\x3d\x2c\x25\xf7\x1d\xf5\x58\x9b\x6e\x80\x55\x68\x91\x40\xda\x4f\xfc\x62\x70\x85\x6d\xde\xe2\x18\x52\x85\x6c\x05\x55\x6c\x46\x19\x1d\x1f\xc6\xd3\x7a\x20\x47\x3a\xd6\x0f\x91\xc6\x57\xaf\x5c\x43\xcf\x91\x0c\xec\x58\x9e\xff\xee\xf9\x9b\x3c\x09\xa1\xb6\xb3\x5c\xa9\xfa\x1b\x00\x00\xff\xff\xf1\x9d\x6f\x4c\x40\x03\x00\x00") func testE2eTestingManifestsStorageCsiMockCsiMockDriverResizerYamlBytes() ([]byte, error) { return bindataRead( @@ -2625,7 +2625,7 @@ func testE2eTestingManifestsStorageCsiMockCsiMockDriverResizerYaml() (*asset, er return a, nil } -var _testE2eTestingManifestsStorageCsiMockCsiMockDriverYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x55\x4d\x8f\xdb\x36\x10\xbd\xfb\x57\x0c\x9c\x1e\x92\x03\xa5\x75\x82\x45\x03\x01\x3e\x6c\xd6\x2e\x10\xb4\xeb\x0d\xe2\xb4\x57\x83\xa6\xc6\xd2\xc0\x12\x49\x90\x23\xa1\xfe\xf7\x05\x25\x6f\x56\x5f\xf6\xee\xb6\xc7\xfa\x44\x93\x33\x6f\x66\xde\xbc\x19\x1d\x49\xa7\x09\x6c\x59\x32\x1e\xaa\x62\x8b\x3c\x93\x96\xfe\x42\xe7\xc9\xe8\x04\xa4\xb5\x3e\xae\x17\xb3\x12\x59\xa6\x92\x65\x32\x03\xd0\xb2\xc4\x04\x94\x27\x51\x1a\x75\xb4\x45\x95\x91\x9e\x79\x8b\x2a\x3c\x7a\x2c\x50\xb1\x71\xe1\x0c\x50\x4a\x56\xf9\x1f\x72\x8f\x85\x6f\x2f\x20\x20\x8e\x9c\x01\x1c\xda\x82\x94\xf4\x09\x2c\x66\x00\x8c\xa5\x2d\x24\xe3\x19\xa4\x13\x3b\xfc\x8a\x1e\xde\x25\x44\x80\xa7\x94\x9a\x33\xba\x9a\x14\xde\x29\x65\x2a\xcd\x9b\x5e\x05\x67\x13\x65\x34\x4b\xd2\xe8\x3a\xd0\xa2\x53\xac\x75\xa6\xa6\xc0\x0a\xba\x9f\xef\x00\x54\xca\x0c\x13\xc8\x94\x8b\xc8\xc4\xc7\xcf\x5e\x78\x96\x19\xe9\x4c\x28\x4f\xf1\xc0\x2f\xa9\x3f\x46\x37\xd1\x8d\x70\x6a\xd1\x81\x90\x2e\xeb\x84\x6c\xc3\xce\x45\xf0\x17\x32\x4d\x1d\x7a\xbf\xfc\xe5\xfd\xdd\x6a\xf5\x7d\xbd\xdd\x7e\x98\xf7\x0c\xdf\xc1\x0f\x63\x4d\x61\xb2\x13\xf8\xca\x5a\xe3\x18\xc8\x83\x46\x4c\x31\x85\x83\x71\xc0\x39\x82\x35\x29\x38\xf4\x2a\xc7\xb4\x2a\x48\x67\xc0\xe8\x79\x00\xf3\x7e\xee\xd9\x38\x99\x21\x28\x69\xa5\x22\x3e\xcd\x81\x74\xa8\x7b\x17\x28\xda\xd5\xa6\xa8\x4a\x8c\x32\xf3\x21\x1a\x67\x7a\x40\xc9\x95\x43\x91\x49\x46\xbf\x7c\xca\x68\xc9\xae\xc2\xf9\xc8\xba\x5e\xde\x76\x2f\x51\xd7\xc3\xda\x5b\xca\xcf\x05\xf7\xde\x00\x6a\x59\x54\x98\x40\x7c\x26\x37\xf2\xcf\xfd\x6b\x9e\x9b\x34\x1f\x42\x8f\x47\x94\x96\xe1\xf6\x9b\xe4\xbc\x75\x1f\x00\xb7\x41\x03\x1c\xb2\x48\xc9\x8d\x24\x90\x3a\xaa\xd1\x09\x87\x19\x79\x76\xf2\x6d\x1a\xd0\x26\x45\x31\x44\x48\xea\x45\xf4\x31\xba\x79\x41\x09\x22\x30\x36\xba\xeb\x8a\xe3\x12\x19\xad\xe5\xb1\xda\x63\x81\xfc\x33\x2c\x93\xd1\xc2\x4a\xce\x97\x71\x2d\x5d\x5c\xd0\x3e\x3e\x9b\xc4\xed\xec\xf8\xf8\x69\x30\xa6\x40\x2f\xf6\xeb\xf7\x3f\xbf\xac\x77\x9b\xc7\xd5\x7a\xb7\xb9\x7b\x58\x4f\xb5\xed\x37\x67\xca\x64\xf0\x00\x70\x20\x2c\xd2\xef\x78\x18\xbf\x84\xc9\x7e\xde\x44\xf5\x62\xc2\xa0\x71\x6e\x7b\x1a\xa6\x3d\x0a\x3c\x87\xe1\xee\x98\x7a\x54\x95\x23\x3e\xdd\x1b\xcd\xf8\x37\xf7\xc3\x58\x47\x35\x15\x98\x61\x9a\x40\x90\xeb\x2b\xa4\x74\x5d\x48\x17\x65\x34\x74\xec\xb6\x63\x02\xa1\xd7\xad\x29\x39\x96\xfd\xb6\x5c\x97\x60\x30\x3e\xcb\x2f\xa9\x3f\x45\x8b\x17\x45\x37\x17\x22\x84\x59\x06\xc7\xe8\xbc\x19\xa2\xe3\x67\x1f\x91\x19\x4f\xb4\xb0\xe8\x4a\xf2\x9e\x6a\x14\x2c\x5d\x86\xdc\xe8\x6b\x0e\xef\x60\x8f\x4a\x56\x1e\xc1\x1c\x20\x67\xb6\x3e\x89\xe3\x8c\x38\xaf\xf6\x91\x32\x65\xa3\x3b\xa7\x91\xd1\x77\x8f\xe4\x7d\x85\x3e\xfe\xf5\xf6\xf6\xd3\xed\x6b\x84\x77\xbf\xfd\xba\x5b\x6f\x56\xdf\x1e\xbf\x6e\x7e\xbc\x6d\x5b\xfc\xff\xc4\xfb\x1f\xf6\xe0\xd8\x79\xb4\x3e\x4c\xea\x07\x68\xad\xb9\x33\x56\x66\x8d\x94\x13\xf8\x42\x29\x39\x54\xe1\x8f\x2c\x26\x63\x37\x3e\xd6\x90\x9e\x8a\xdf\x9a\xe4\xc6\x1c\xa7\x43\xb5\x99\x21\xab\xb8\x6b\xd3\xd2\xd1\xfb\xae\xe7\xc6\xb7\xd6\x7d\x4a\x2f\x54\x36\x58\x8c\x3d\x1f\x3e\x59\x4c\x60\xd5\x54\x65\xdc\xe9\xd1\xdd\x3b\x94\xdc\xed\xc6\x95\x6f\xcb\xdb\xd2\x18\x12\xfc\xda\xd0\x17\x28\xfd\x77\x2c\xec\xce\xbb\xe9\x74\x2d\x95\x51\x0a\x2f\x2e\xb4\x61\x4f\x95\xd1\x07\xca\x1e\xa4\x4d\x26\xd6\x63\x67\xa1\x89\xd6\xf1\x9f\x00\x00\x00\xff\xff\x01\x04\x5d\xf5\xc7\x0a\x00\x00") +var _testE2eTestingManifestsStorageCsiMockCsiMockDriverYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x55\x4d\x8f\xdb\x46\x0c\xbd\xfb\x57\x10\x4e\x0f\xc9\x41\x52\x8d\xc5\xb6\x85\x00\x1f\x36\x6b\x17\x08\xda\xf5\x06\x71\xda\xab\x31\x1e\xd1\x32\x61\x69\x66\xc0\xa1\x84\xfa\xdf\x17\x23\x79\x13\x7d\x79\x3f\xda\x63\x16\x58\x60\x3c\x43\x3e\x92\x8f\x8f\xd4\x89\x4c\x96\xc2\x56\x94\xe0\xa1\x2a\xb6\x28\x33\xe5\xe8\x6f\x64\x4f\xd6\xa4\xa0\x9c\xf3\x49\xbd\x98\x95\x28\x2a\x53\xa2\xd2\x19\x80\x51\x25\xa6\xa0\x3d\x45\xa5\xd5\x27\x57\x54\x39\x99\x99\x77\xa8\xc3\xa3\xc7\x02\xb5\x58\x0e\x67\x80\x52\x89\x3e\xfe\xa9\xf6\x58\xf8\xf6\x02\x02\xe2\xc8\x19\x80\xd1\x15\xa4\x95\x4f\x61\x31\x03\x10\x2c\x5d\xa1\x04\x2f\x20\x9d\xd8\xe1\xaf\xe8\xe1\x5d\x43\x04\x78\x4a\xa9\x39\x23\xd7\xa4\xf1\x4e\x6b\x5b\x19\xd9\xf4\x2a\xb8\x98\x68\x6b\x44\x91\x41\xee\x40\x47\x9d\x62\x1d\xdb\x9a\x02\x2b\xc8\xdf\xde\x01\xa8\x54\x39\xa6\x70\xfa\xcd\xc7\xb9\xe6\x98\x6c\xe2\x29\x8f\xbc\x58\x56\x39\x26\x03\xbf\xb4\x5e\xc4\xbf\xc4\x3f\x77\xdc\x15\xe7\x9d\x70\x6d\xc8\x79\x14\x05\x3f\x95\x65\x8c\xde\x2f\x7f\x7a\x7f\xb7\x5a\x7d\x59\x6f\xb7\x1f\xe6\x3d\xc3\x77\xf0\xd5\x3a\x5b\xd8\xfc\x0c\xbe\x72\xce\xb2\x00\x79\x30\x88\x19\x66\x70\xb0\x0c\x72\x44\x70\x36\x03\x46\xaf\x8f\x98\x55\x05\x99\x1c\x04\xbd\x0c\x60\xde\xcf\x2f\xe9\x82\x56\x4e\x69\x92\xf3\x1c\xc8\x84\x9a\x77\x81\x9e\x5d\x6d\x8b\xaa\xc4\x38\xb7\x1f\xe2\x71\xa6\x07\x54\x52\x31\x46\xb9\x12\xf4\xcb\xa7\x8c\x96\xc2\x15\xce\x47\xd6\xf5\xf2\xb6\x7b\x89\xa6\x1e\xd6\xde\xd2\x7d\x29\xb8\xf7\x06\x50\xab\xa2\xc2\x14\x02\xa9\xe1\x3f\xf6\xdf\x7b\xd7\x3c\x37\x69\x3e\x84\xfe\x8e\x28\x2d\xc3\xed\x67\x25\xc7\xd6\x7d\x00\xdc\x06\x0d\x70\x28\x51\x46\x3c\x6a\x7f\xc6\x54\x23\x47\x8c\x39\x79\x61\xf5\xb6\xfe\x1b\x9b\x61\x34\x44\x08\x4a\xb8\x79\x51\x09\x51\x60\x6c\x74\xd7\x15\xc7\x35\x32\x5a\xcb\x53\xb5\xc7\x02\xe5\x5b\x58\x21\x6b\x22\xa7\xe4\xb8\x4c\x6a\xc5\x49\x41\xfb\xe4\x62\x92\xb4\x73\xe3\x93\xa7\xa1\x98\x02\xbd\xda\xaf\x3f\xfe\xfa\xb8\xde\x6d\x1e\x57\xeb\xdd\xe6\xee\x61\x3d\xd5\xb6\xdf\xd9\x96\xe9\xe0\x01\xe0\x40\x58\x64\x5f\xf0\x30\x7e\x09\x53\xfd\x7d\x0b\xd5\x8b\x09\x83\xc6\xb9\xed\x69\x98\xf4\x38\xf0\x1c\x06\xbb\x63\xea\x51\x57\x4c\x72\xbe\xb7\x46\xf0\x1f\xe9\x87\x71\x4c\x35\x15\x98\x63\x96\x42\x90\xeb\x2b\xa4\xf4\xbc\x90\xae\xca\x68\xe8\xd8\x6d\xc7\x04\x42\xaf\x5b\x53\x72\x2c\xfb\x6d\x79\x5e\x82\xc1\xf8\x22\xbf\xb4\xbe\x89\x17\xaf\x59\x3f\x21\xcc\x32\x38\xc6\x17\x94\x38\x80\x93\x1d\x4f\x74\xe4\x90\x4b\xf2\x9e\x6a\x8c\x44\x71\x8e\xd2\xe8\x6b\x0e\xef\x60\x8f\x5a\x55\x1e\xc1\x1e\xe0\x28\xe2\x7c\x9a\x24\x39\xc9\xb1\xda\xc7\xda\x96\x8d\xee\xd8\xa0\xa0\xef\x1e\xc9\xfb\x0a\x7d\xf2\xeb\xed\xed\xcd\xed\x6b\x84\x77\xbf\xfd\xb4\x5b\x6f\x56\x9f\x1f\x3f\x6d\xbe\xbe\x6d\x5b\xfc\x78\xe2\xfd\x1f\x7b\x70\xec\x3c\x5a\x1f\x36\xf3\x03\xb4\xd6\x9c\xad\x53\x79\x23\xe5\x14\x3e\x52\x46\x8c\x3a\xfc\x50\xc5\x64\xec\xc6\xc7\x59\x32\x53\xf1\x5b\x93\xa3\xb5\xa7\xe9\x50\x6d\x66\x28\x3a\xe9\xda\xb4\x74\xf4\xbe\xe9\x47\xeb\x5b\xeb\x3e\xa5\x57\x2a\x1b\x2c\xc6\x9e\x8f\x9c\x1d\xa6\xb0\x6a\xaa\xb2\x7c\x7e\xe4\x7b\x46\x25\xdd\x6e\x3c\xf3\x6d\x79\x5b\x1a\x43\x82\x5f\x1b\xfa\x0a\xa5\xff\x8d\x85\xdd\x65\x37\x9d\x9f\x4b\x65\x94\xc2\x8b\x0b\x6d\xd8\x53\x6d\xcd\x81\xf2\x07\xe5\xd2\x89\xf5\xd8\x59\x68\x51\xeb\xf8\x6f\x00\x00\x00\xff\xff\xbb\x35\xe0\x36\xc3\x0a\x00\x00") func testE2eTestingManifestsStorageCsiMockCsiMockDriverYamlBytes() ([]byte, error) { return bindataRead( @@ -2765,7 +2765,7 @@ func testE2e_nodeTestingManifestsSriovdpSaYaml() (*asset, error) { return a, nil } -var _testImagesMakefile = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x53\xd1\x6e\xe3\x36\x10\x7c\x2e\xbf\x62\x10\xdd\x43\x02\xd8\x72\x62\x14\x3d\xd4\x45\x70\x50\x1c\x35\x11\x92\x93\xae\x92\x72\x41\x9e\x0c\x5a\x5a\x4b\xc4\xd1\xa4\x4a\x52\xb1\x8d\xa2\xff\x5e\x50\x8a\xdb\xfa\x82\xd3\x1b\xb9\x33\xb3\xa3\xd9\x65\x80\xa5\xee\x0e\x46\x34\xad\xc3\xfc\xf2\xea\x23\xca\x96\xf0\xd0\xaf\xc9\x28\x72\x64\x11\xf5\xae\xd5\xc6\x86\x2c\x60\x01\x1e\x45\x45\xca\x52\x8d\x5e\xd5\x64\xe0\x5a\x42\xd4\xf1\xaa\xa5\x63\x65\x82\xaf\x64\xac\xd0\x0a\xf3\xf0\x12\xe7\x1e\x70\xf6\x56\x3a\xbb\xf8\x8d\x05\x38\xe8\x1e\x5b\x7e\x80\xd2\x0e\xbd\x25\xb8\x56\x58\x6c\x84\x24\xd0\xbe\xa2\xce\x41\x28\x54\x7a\xdb\x49\xc1\x55\x45\xd8\x09\xd7\x0e\x6d\xde\x44\x42\x16\xe0\xe5\x4d\x42\xaf\x1d\x17\x0a\x1c\x95\xee\x0e\xd0\x9b\xff\xe3\xc0\xdd\x60\xd8\x7f\xad\x73\xdd\x62\x36\xdb\xed\x76\x21\x1f\xcc\x86\xda\x34\x33\x39\x02\xed\xec\x31\x59\xc6\x69\x11\x4f\xe7\xe1\xe5\x40\x79\x52\x92\xac\x85\xa1\x3f\x7b\x61\xa8\xc6\xfa\x00\xde\x75\x52\x54\x7c\x2d\x09\x92\xef\xa0\x0d\x78\x63\x88\x6a\x38\xed\xfd\xee\x8c\x70\x42\x35\x13\x58\xbd\x71\x3b\x6e\x88\x05\xa8\x85\x75\x46\xac\x7b\x77\x12\xd6\xd1\x9d\xb0\x27\x00\xad\xc0\x15\xce\xa2\x02\x49\x71\x86\x9b\xa8\x48\x8a\x09\x0b\xf0\x9c\x94\xf7\xd9\x53\x89\xe7\x28\xcf\xa3\xb4\x4c\xe2\x02\x59\x8e\x65\x96\xde\x26\x65\x92\xa5\x05\xb2\xdf\x11\xa5\x2f\x78\x48\xd2\xdb\x09\x48\xb8\x96\x0c\x68\xdf\x19\xef\x5f\x1b\x08\x1f\x23\xd5\x3e\xb3\x82\xe8\xc4\xc0\x46\x8f\x86\x6c\x47\x95\xd8\x88\x0a\x92\xab\xa6\xe7\x0d\xa1\xd1\xaf\x64\x94\x50\x0d\x3a\x32\x5b\x61\xfd\x30\x2d\xb8\xaa\x59\x00\x29\xb6\xc2\x71\x37\xdc\xbc\xfb\xa9\x90\xb1\x3c\xbe\x4b\x8a\x32\x7f\xc1\xa7\x6b\x34\x95\x09\x85\x9e\x7d\xfb\x77\x93\xa6\x34\xa7\xa9\x23\xeb\xa6\x62\xcb\x1b\xb2\xec\x2e\x8b\xf2\xcf\x1e\xfa\x91\xdd\x66\xcb\x87\x38\x5f\x2d\xe3\xbc\x5c\xdd\x44\x45\xbc\xfa\x12\x95\xf7\xf8\x74\xcd\xfe\x88\x3f\x3f\x7d\x8d\xf3\x22\xc9\xd2\xeb\xd7\x79\xf8\x6b\x78\xc5\xee\xb2\xc7\x28\xbd\x5b\x1d\x6f\xaf\xc2\xab\x9f\xc3\x5f\x18\xed\x3b\x6d\x1c\x63\x62\xa3\x6a\xda\xe0\xf9\x3e\x2a\xd9\x87\x73\x32\x46\x9b\xe1\xe0\x23\xe7\xff\x0d\xf5\x95\x1b\xe1\xe7\x39\x01\xed\x17\xd8\xf2\x6f\x04\x2e\xe5\x80\xbc\x56\xe4\x2e\x18\xa9\x5a\x6c\x18\x0b\x70\xd3\x0b\x59\xa3\xd2\x35\x8d\x4f\x20\x32\x8d\x5d\x0c\x9b\xe5\xc1\x0b\xdc\x0a\x43\x95\xd3\xe6\x00\xc5\xb7\x64\xfd\x4a\xac\x3d\x65\x44\xc7\x7b\xbe\xed\x24\x8d\x84\xd3\x36\x95\xec\xad\x23\xc3\x3b\x31\xa4\x42\x86\x71\x29\x17\xbe\x3e\xad\xb4\xf2\xab\x4d\x86\xb1\x93\xe3\x82\xfd\x14\xce\x86\xf4\xa6\xbd\x13\x32\xb4\xed\xd8\x0b\x1f\xce\xbd\xe4\xc5\x08\xef\x7a\xdb\x7e\xaf\xf3\x8e\xe7\x41\xa7\xb4\x41\x69\xca\x55\x3d\x0a\xfc\xa0\xd5\x8a\xab\x7a\x35\x92\xff\xf2\xe4\xbf\x19\x0b\xbf\xdc\x67\xe9\xcb\xd0\x11\xef\x85\x70\xb4\xf4\x9d\xa3\x7f\x02\x00\x00\xff\xff\xae\x6d\xd6\xed\x78\x04\x00\x00") +var _testImagesMakefile = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x53\xd1\x6e\xe3\x36\x10\x7c\x2e\xbf\x62\x10\xdd\x43\x02\xd8\x72\x62\xa0\x38\xd4\x45\x70\x50\x1c\x35\x11\x92\x93\xae\x92\x72\x41\x9e\x0c\x5a\x5a\x4b\xc4\xd1\xa4\x4a\x52\xb1\x8d\xa2\xff\x5e\x50\x8a\xdb\x3a\x41\xf5\x46\xee\xcc\xec\x68\x76\x19\x60\xa9\xbb\x83\x11\x4d\xeb\x30\xbf\xbc\xfa\x8c\xb2\x25\x3c\xf4\x6b\x32\x8a\x1c\x59\x44\xbd\x6b\xb5\xb1\x21\x0b\x58\x80\x47\x51\x91\xb2\x54\xa3\x57\x35\x19\xb8\x96\x10\x75\xbc\x6a\xe9\x58\x99\xe0\x3b\x19\x2b\xb4\xc2\x3c\xbc\xc4\xb9\x07\x9c\xbd\x95\xce\x2e\x7e\x65\x01\x0e\xba\xc7\x96\x1f\xa0\xb4\x43\x6f\x09\xae\x15\x16\x1b\x21\x09\xb4\xaf\xa8\x73\x10\x0a\x95\xde\x76\x52\x70\x55\x11\x76\xc2\xb5\x43\x9b\x37\x91\x90\x05\x78\x79\x93\xd0\x6b\xc7\x85\x02\x47\xa5\xbb\x03\xf4\xe6\xbf\x38\x70\x37\x18\xf6\x5f\xeb\x5c\xb7\x98\xcd\x76\xbb\x5d\xc8\x07\xb3\xa1\x36\xcd\x4c\x8e\x40\x3b\x7b\x4c\x96\x71\x5a\xc4\xd3\x79\x78\x39\x50\x9e\x94\x24\x6b\x61\xe8\x8f\x5e\x18\xaa\xb1\x3e\x80\x77\x9d\x14\x15\x5f\x4b\x82\xe4\x3b\x68\x03\xde\x18\xa2\x1a\x4e\x7b\xbf\x3b\x23\x9c\x50\xcd\x04\x56\x6f\xdc\x8e\x1b\x62\x01\x6a\x61\x9d\x11\xeb\xde\x9d\x84\x75\x74\x27\xec\x09\x40\x2b\x70\x85\xb3\xa8\x40\x52\x9c\xe1\x26\x2a\x92\x62\xc2\x02\x3c\x27\xe5\x7d\xf6\x54\xe2\x39\xca\xf3\x28\x2d\x93\xb8\x40\x96\x63\x99\xa5\xb7\x49\x99\x64\x69\x81\xec\x37\x44\xe9\x0b\x1e\x92\xf4\x76\x02\x12\xae\x25\x03\xda\x77\xc6\xfb\xd7\x06\xc2\xc7\x48\xb5\xcf\xac\x20\x3a\x31\xb0\xd1\xa3\x21\xdb\x51\x25\x36\xa2\x82\xe4\xaa\xe9\x79\x43\x68\xf4\x2b\x19\x25\x54\x83\x8e\xcc\x56\x58\x3f\x4c\x0b\xae\x6a\x16\x40\x8a\xad\x70\xdc\x0d\x37\x1f\x7e\x2a\x64\x2c\x8f\xef\x92\xa2\xcc\x5f\xf0\xe5\x1a\x4d\x65\x42\xa1\x67\x3f\xfe\xd9\xa4\x29\xcd\x69\xea\xc8\xba\xa9\xd8\xf2\x86\x2c\xbb\xcb\xa2\xfc\xab\x87\x7e\x66\xb7\xd9\xf2\x21\xce\x57\xcb\x38\x2f\x57\x37\x51\x11\xaf\xbe\x45\xe5\x3d\xbe\x5c\xb3\xdf\xe3\xaf\x4f\xdf\xe3\xbc\x48\xb2\xf4\xfa\x75\x1e\xfe\x12\x5e\xb1\xbb\xec\x31\x4a\xef\x56\xc7\xdb\xab\xf0\xea\xe7\xf0\x92\xd1\xbe\xd3\xc6\x31\x26\x36\xaa\xa6\x0d\x9e\xef\xa3\x92\x7d\x3a\x27\x63\xb4\x19\x0e\x3e\x72\xfe\xef\x50\x5f\xb9\x11\x7e\x9e\x13\xd0\x7e\x81\x2d\xff\x41\xe0\x52\x0e\xc8\x6b\x45\xee\x82\x91\xaa\xc5\x86\xb1\x00\x37\xbd\x90\x35\x2a\x5d\xd3\xf8\x04\x22\xd3\xd8\xc5\xb0\x59\x1e\xbc\xc0\xad\x30\x54\x39\x6d\x0e\x50\x7c\x4b\xd6\xaf\xc4\xda\x53\x46\x74\xbc\xe7\xdb\x4e\xd2\x48\x38\x6d\x53\xc9\xde\x3a\x32\xbc\x13\x43\x2a\x64\x18\x97\x72\xe1\xeb\xd3\x4a\x2b\xbf\xda\x64\x18\x3b\x39\x2e\xd8\x4f\xe1\x6c\x48\x6f\xda\x3b\x21\x43\xdb\x8e\xbd\xf0\xe9\xdc\x4b\x5e\x8c\xf0\xae\xb7\xed\x7b\x9d\x0f\x3c\x0f\x3a\xa5\x0d\x4a\x53\xae\xea\x51\xe0\x7f\x5a\xad\xb8\xaa\x57\x23\xf9\x4f\x4f\xfe\x8b\xb1\xf0\xdb\x7d\x96\xbe\x0c\x1d\xf1\x51\x08\x47\x4b\xef\x1c\xfd\x1d\x00\x00\xff\xff\x3b\x8d\xfd\x02\x78\x04\x00\x00") func testImagesMakefileBytes() ([]byte, error) { return bindataRead( @@ -2925,7 +2925,7 @@ func testImagesAgnhostOwners() (*asset, error) { return a, nil } -var _testImagesAgnhostVersion = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x32\xd2\x33\x32\xe4\x02\x04\x00\x00\xff\xff\xa4\x1b\x49\x5c\x05\x00\x00\x00") +var _testImagesAgnhostVersion = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x32\xd2\x33\x32\xe2\x02\x04\x00\x00\xff\xff\x67\x48\x64\x77\x05\x00\x00\x00") func testImagesAgnhostVersionBytes() ([]byte, error) { return bindataRead( @@ -2945,7 +2945,7 @@ func testImagesAgnhostVersion() (*asset, error) { return a, nil } -var _testImagesAgnhostAgnhostGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x97\x4d\x6f\xe3\x36\x13\xc7\xcf\xe6\xa7\x18\xe8\xf0\xc0\x5e\xc4\x52\x36\xcf\xa5\x4d\xd1\x83\xeb\xbc\xac\xb1\xa9\xb3\x88\xbc\x0d\xf6\x48\x53\x63\x89\x08\x45\xaa\x24\x15\xc5\x58\xec\x77\x2f\x86\x96\x1d\x7b\x2b\xbb\xf2\x29\x7c\xf9\xfd\x67\xc6\x14\xf9\x0f\x99\x7c\x60\x53\x53\xad\xad\xcc\x0b\x0f\x57\x97\x1f\x7f\x85\x45\x81\xf0\xb9\x5e\xa2\xd5\xe8\xd1\xc1\xa4\xf6\x85\xb1\x2e\x66\xec\x41\x0a\xd4\x0e\x33\xa8\x75\x86\x16\x7c\x81\x30\xa9\xb8\x28\x10\xda\x99\x0b\xf8\x0b\xad\x93\x46\xc3\x55\x7c\x09\x43\x02\xa2\x76\x2a\x1a\xfd\xc6\xd6\xa6\x86\x92\xaf\x41\x1b\x0f\xb5\x43\xf0\x85\x74\xb0\x92\x0a\x01\xdf\x04\x56\x1e\xa4\x06\x61\xca\x4a\x49\xae\x05\x42\x23\x7d\x11\x92\xb4\x21\x62\xf6\xad\x0d\x60\x96\x9e\x4b\x0d\x1c\x84\xa9\xd6\x60\x56\xfb\x14\x70\xcf\x18\x00\x40\xe1\x7d\x75\x9d\x24\x4d\xd3\xc4\x3c\x54\x19\x1b\x9b\x27\x6a\x43\xb9\xe4\x61\x36\xbd\x9d\xa7\xb7\xe3\xab\xf8\x92\xb1\xaf\x5a\xa1\x73\x60\xf1\xef\x5a\x5a\xcc\x60\xb9\x06\x5e\x55\x4a\x0a\xbe\x54\x08\x8a\x37\x60\x2c\xf0\xdc\x22\x66\xe0\x0d\xd5\xd9\x58\xe9\xa5\xce\x2f\xc0\x99\x95\x6f\xb8\x45\x96\x49\xe7\xad\x5c\xd6\xfe\x60\x81\xb6\x55\x49\x07\xfb\x80\xd1\xc0\x35\x44\x93\x14\x66\x69\x04\x7f\x4c\xd2\x59\x7a\xc1\x9e\x67\x8b\x4f\x8f\x5f\x17\xf0\x3c\x79\x7a\x9a\xcc\x17\xb3\xdb\x14\x1e\x9f\x60\xfa\x38\xbf\x99\x2d\x66\x8f\xf3\x14\x1e\xef\x60\x32\xff\x06\x9f\x67\xf3\x9b\x0b\x40\xe9\x0b\xb4\x80\x6f\x95\xa5\xda\x8d\x05\x49\x4b\x87\x59\xcc\x52\xc4\x83\xe4\x2b\xb3\x29\xc6\x55\x28\xe4\x4a\x0a\x50\x5c\xe7\x35\xcf\x11\x72\xf3\x8a\x56\x4b\x9d\x43\x85\xb6\x94\x8e\x3e\x9e\x03\xae\x33\xa6\x64\x29\x3d\xf7\xa1\xff\xaf\x9f\x13\xb3\x0f\x09\x63\x15\x17\x2f\x14\xa4\xe4\x52\x33\x26\xcb\xca\x58\x0f\x43\x36\x88\x56\x8a\xe7\x11\x63\x83\x28\x97\xbe\xa8\x97\xb1\x30\x65\xe2\xaa\xd5\xc7\xff\x27\xc2\x2c\x2d\x0f\x53\x2f\xbf\xb8\x58\x9a\xe4\x45\x99\x3c\x79\xbd\x8a\xd8\x80\xd7\x99\xf4\x95\x35\x6f\x6b\xd8\x4d\xee\x76\x61\xe2\xd1\xf9\x44\x96\x3c\x47\x97\xf0\x5c\x17\xc6\xf9\x24\x28\xc6\x41\x12\xed\x45\x3c\x2d\x12\x46\x6b\x14\x3e\x62\x03\x61\x33\x61\xf4\x6b\x83\xcb\xc2\x98\x97\xbe\x49\x85\xcd\xc6\x24\xdb\x6c\xf4\x71\xab\xee\x9f\x3f\xd3\xae\x3f\x8c\xda\xdb\x75\x65\xa4\xf6\x63\x9a\x46\xdb\x5f\xba\xe2\x2f\x98\x4b\xef\xd0\xbe\x9e\x23\xcb\x6b\x74\x7e\x79\xd6\x2f\x92\x5a\xa8\x9a\x8a\x13\x4a\xa2\xf6\xfd\x85\x4a\xbe\xa2\x46\x47\xeb\xa1\x4c\xee\x72\xd4\x7d\x3f\x02\xe1\xe3\x1c\x35\x5a\xee\xcd\x19\xbf\xae\x34\xb5\xf6\x34\xd1\x5f\xa2\xf1\x3c\x18\xdf\x50\x9c\x25\x68\xcb\xd1\xc6\x69\xee\xfb\x2e\x80\x36\x63\xc2\xc7\x07\xe2\xb3\x0e\xcf\x7e\x84\x73\xcf\x90\xa9\x50\xcb\xac\x44\xcf\x33\xee\x79\x7f\x5d\xc5\x6b\x87\x11\x1b\x90\x51\xac\x8c\x6d\xb8\xcd\x36\xdb\xba\x6f\xd1\x24\x1c\xb7\xca\xb3\x4f\x04\x89\x03\x6f\xd1\x09\xa3\x5d\x5d\xa2\x15\xde\xaa\xbe\xc9\x2d\x3a\x53\x5b\x81\xe3\xad\x98\x1a\xde\x1a\xa5\x42\xd4\x70\xd2\x08\xd4\xbc\xc4\xbe\x31\x83\x68\xbc\x55\x45\x6c\x40\x50\x83\xcb\xcd\xb1\xed\x1b\x25\x7c\xc3\x9d\xaa\xff\x8a\xec\xcc\x6b\xc4\xd8\xaa\xd6\x22\x38\xf9\x70\x04\xdf\xd9\xc0\x1a\xe3\xa7\x65\x06\xd7\xbf\xc3\xff\x82\x69\xc7\x53\x53\x96\x5c\x67\xdf\xbf\x3a\xbc\x86\x88\x57\x55\xb4\xfb\x77\x7f\x0d\xd1\x55\x7c\x75\x19\xfd\x60\x3b\x61\x3c\xc9\xb2\x56\x31\x7c\x77\xf6\x78\x5a\x66\x13\xea\x7d\xa1\xde\xa8\x93\x6e\x0d\x9a\xd0\xe9\xa6\x79\x84\x3b\xb0\xef\x80\x5b\x52\xb4\xce\xfc\xbc\x19\xef\xd6\x66\xda\x91\xe0\x66\x9e\xa6\xf5\x6a\x25\xdf\xfe\x93\x0a\x0b\xfb\x20\xdd\x91\x5a\x5a\xf2\xd6\x8b\x4f\xc6\x79\xd7\x0d\xbd\x9b\x79\x60\x77\xbd\x45\xd8\xc7\xdd\x9a\x03\x17\x27\xd9\x1d\x7f\xc1\x7b\xe9\x37\x05\x75\x6b\x76\x16\x4e\xfc\xfd\xb6\xd3\xcd\xfe\xe4\xdd\xa4\x98\xe9\xe9\x66\x68\x1a\x86\xba\x75\x5b\xeb\x26\xc1\x43\xdb\x3e\x42\x6e\x9c\x3d\x80\x26\x77\xf7\x5b\xd3\xee\xa6\x77\x06\x4d\xfc\x9f\xdb\x4e\x37\xab\x31\x50\x73\x3c\x3e\x4f\x66\xdc\x32\xd4\x3c\xca\x6d\x33\xce\xf1\x54\xbe\x60\xb2\x01\x33\xa9\xe6\xe1\xbb\x9d\x22\x77\x3b\xfe\x1d\x3f\xb1\xed\x83\x37\x12\xfd\x85\x1a\x47\x98\xe0\x60\x01\x0a\xad\xe3\xd4\x81\xbb\x6e\x05\x77\x9b\xc1\x53\xfb\xed\x27\x6b\x24\xe5\x53\x6b\x7b\xd3\x76\x7c\xba\x33\xbd\xee\x10\x07\x3e\x48\x01\xc2\x5e\xfd\xd4\x0e\x74\x6b\x0e\x5c\x8f\x34\x54\xe3\xf3\x76\xa0\x5b\xb3\x77\xf0\x4f\x9e\xf5\xc3\x7f\x56\xdb\xe0\x54\x94\x14\x38\x11\x82\x36\xd9\xcc\xb9\x1a\xed\x8d\x74\x82\xee\xc3\xeb\x11\x63\x83\x24\x81\xf9\xe3\xe2\x76\x28\x14\xd9\x57\xbd\x1c\x5d\x43\x6a\x4a\x04\x2a\xd5\x01\xb7\x08\x15\x77\x8e\x6e\xce\xca\xe4\x39\xfd\xb5\xa8\x38\xdd\xed\xe9\xf6\xeb\xe8\x61\x00\x0d\x82\x6e\x9f\x0c\x4b\x84\xf0\x96\xf0\x26\x84\xe6\x22\x3c\x78\x7c\x81\x65\x0c\x0b\x7a\x07\x35\x52\x29\xe0\xca\xd1\xeb\x42\xa8\x3a\x0b\x37\xf8\x92\x9e\x1a\x74\xef\xae\xac\xd4\x14\xbb\x40\x55\xc5\xe1\xba\x44\x29\xef\x28\x53\xb0\x68\xca\x19\x53\x37\x45\xff\xfd\x07\x1b\xd0\xb5\x3a\x9e\x69\xe9\x03\x32\xdc\xe7\xf7\x56\xe9\x0b\x59\xa5\xf3\xa8\x5b\x6c\x44\xeb\x76\x6f\xda\x38\xc7\x54\xb7\x6f\x28\x6a\x8f\xc3\x11\xfb\xc1\xfe\x09\x00\x00\xff\xff\x49\x9c\xd0\x38\x3e\x0e\x00\x00") +var _testImagesAgnhostAgnhostGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x97\x4f\x93\xda\x38\x13\xc6\xcf\xd6\xa7\xe8\xf2\xe1\x2d\x48\x0d\x76\xc2\x7b\xd9\x9d\xad\x3d\xb0\xcc\x9f\x50\x99\x65\x52\x63\xb2\x53\x39\x0a\xb9\xb1\x55\x23\x4b\x5e\x49\x1e\x86\x4a\xe5\xbb\x6f\xb5\x30\x04\xb2\x86\x35\x27\x2c\xe9\xf7\x74\x37\xb2\xf4\x58\x4a\xdf\xb1\xa9\xa9\x37\x56\x16\xa5\x87\xf1\xfb\x0f\xbf\xc2\xa2\x44\xf8\xd4\x2c\xd1\x6a\xf4\xe8\x60\xd2\xf8\xd2\x58\x97\x30\xf6\x20\x05\x6a\x87\x39\x34\x3a\x47\x0b\xbe\x44\x98\xd4\x5c\x94\x08\xed\xc8\x15\xfc\x85\xd6\x49\xa3\x61\x9c\xbc\x87\x01\x01\x71\x3b\x14\x0f\x7f\x63\x1b\xd3\x40\xc5\x37\xa0\x8d\x87\xc6\x21\xf8\x52\x3a\x58\x49\x85\x80\x6f\x02\x6b\x0f\x52\x83\x30\x55\xad\x24\xd7\x02\x61\x2d\x7d\x19\x92\xb4\x21\x12\xf6\xb5\x0d\x60\x96\x9e\x4b\x0d\x1c\x84\xa9\x37\x60\x56\x87\x14\x70\xcf\x18\x00\x40\xe9\x7d\x7d\x9d\xa6\xeb\xf5\x3a\xe1\xa1\xca\xc4\xd8\x22\x55\x5b\xca\xa5\x0f\xb3\xe9\xed\x3c\xbb\x1d\x8d\x93\xf7\x8c\x7d\xd1\x0a\x9d\x03\x8b\x7f\x37\xd2\x62\x0e\xcb\x0d\xf0\xba\x56\x52\xf0\xa5\x42\x50\x7c\x0d\xc6\x02\x2f\x2c\x62\x0e\xde\x50\x9d\x6b\x2b\xbd\xd4\xc5\x15\x38\xb3\xf2\x6b\x6e\x91\xe5\xd2\x79\x2b\x97\x8d\x3f\x9a\xa0\x5d\x55\xd2\xc1\x21\x60\x34\x70\x0d\xf1\x24\x83\x59\x16\xc3\x1f\x93\x6c\x96\x5d\xb1\xe7\xd9\xe2\xe3\xe3\x97\x05\x3c\x4f\x9e\x9e\x26\xf3\xc5\xec\x36\x83\xc7\x27\x98\x3e\xce\x6f\x66\x8b\xd9\xe3\x3c\x83\xc7\x3b\x98\xcc\xbf\xc2\xa7\xd9\xfc\xe6\x0a\x50\xfa\x12\x2d\xe0\x5b\x6d\xa9\x76\x63\x41\xd2\xd4\x61\x9e\xb0\x0c\xf1\x28\xf9\xca\x6c\x8b\x71\x35\x0a\xb9\x92\x02\x14\xd7\x45\xc3\x0b\x84\xc2\xbc\xa2\xd5\x52\x17\x50\xa3\xad\xa4\xa3\x97\xe7\x80\xeb\x9c\x29\x59\x49\xcf\x7d\x68\xff\xeb\xef\x24\xec\x5d\xca\x58\xcd\xc5\x0b\x05\xa9\xb8\xd4\x8c\xc9\xaa\x36\xd6\xc3\x80\x45\xf1\x4a\xf1\x22\x66\x2c\x8a\x0b\xe9\xcb\x66\x99\x08\x53\xa5\xae\x5e\x7d\xf8\x7f\x2a\xcc\xd2\xf2\x30\xf4\xf2\x8b\x4b\xa4\x49\x5f\x94\x29\xd2\xd7\x71\xcc\x22\xde\xe4\xd2\xd7\xd6\xbc\x6d\x60\x3f\xb8\x5f\x85\xa9\x47\xe7\x53\x59\xf1\x02\x5d\xca\x0b\x5d\x1a\xe7\xd3\xa0\x18\x05\x49\x7c\x10\xf1\xbc\x48\x18\xad\x51\xf8\x98\x45\xc2\xe6\xc2\xe8\xd7\x35\x2e\x4b\x63\x5e\xfa\x26\x15\x36\x1f\x91\x6c\xbb\xd0\x47\xad\xba\x7f\xfe\x5c\xbb\xfe\x30\x6a\x6f\x37\xb5\x91\xda\x8f\x68\x18\x6d\x7f\xe9\x8a\xbf\x60\x21\xbd\x43\xfb\x7a\x89\xac\x68\xd0\xf9\xe5\x45\xff\x48\x6a\xa1\x1a\x2a\x4e\x28\x89\xda\xf7\x17\x2a\xf9\x8a\x1a\x1d\xcd\x87\x32\x85\x2b\x50\xf7\x7d\x09\x84\x8f\x0a\xd4\x68\xb9\x37\x17\xfc\xbb\xca\x34\xda\xd3\x40\x7f\x89\xc6\xcb\x60\x7c\x43\x71\x91\xa0\x2d\x47\x1b\xa7\xb9\xef\x3b\x01\xda\x8c\x08\x1f\x1d\x89\x2f\xda\x3c\x87\x11\x2e\xdd\x43\xa6\x46\x2d\xf3\x0a\x3d\xcf\xb9\xe7\xfd\x75\x35\x6f\x1c\xc6\x2c\x22\xa3\x58\x19\xbb\xe6\x36\xdf\x2e\xeb\xbe\x45\x93\x70\xd4\x2a\x2f\xde\x11\x24\x0e\xbc\x45\x27\x8c\x76\x4d\x85\x56\x78\xab\xfa\x26\xb7\xe8\x4c\x63\x05\x8e\x76\x62\x7a\xf0\xd6\x28\x15\xa2\x86\x9d\x46\xa0\xe6\x15\xf6\x8d\x19\x44\xa3\x9d\x2a\x66\x11\x41\x6b\x5c\x6e\xb7\x6d\xdf\x28\xe1\x1d\xee\x55\xfd\x67\x64\x6f\x5e\x43\xc6\x56\x8d\x16\xc1\xc9\x07\x43\xf8\xc6\x22\x6b\x8c\x9f\x56\x39\x5c\xff\x0e\xff\x0b\xa6\x9d\x4c\x4d\x55\x71\x9d\x7f\x63\x51\xf4\xc5\xe1\x35\x7d\x62\x21\xe6\x75\x1d\x5f\xb1\x28\x6a\xbf\xfb\xd7\x10\x8f\x93\xf1\x98\xba\xbe\xb3\x7d\x90\x64\x92\xe7\xad\x7a\xf0\xc3\xe5\x93\x69\x95\x4f\xa8\xf5\x99\x5a\xc3\x4e\xba\x35\x6b\x42\xa7\xdb\xc7\x13\xdc\x91\x95\x07\xdc\x92\xa2\x75\xe9\xe7\x6d\x7f\xb7\x36\xd7\x8e\x04\x37\xf3\x2c\x6b\x56\x2b\xf9\xf6\x9f\x54\x98\xe4\x07\xe9\x4e\xd4\xd2\x92\xb7\x5e\x7c\x34\xce\xbb\x6e\xe8\x87\xb1\x07\x76\xdf\x5a\x84\x35\xdd\xad\x39\x72\x74\x92\xdd\xf1\x17\xbc\x97\x7e\x5b\x50\xb7\x66\x6f\xe7\xc4\xdf\xef\x1a\xdd\xec\x4f\x3e\x4e\x8a\x99\x9e\x6e\xbb\xa6\xa1\xab\x5b\xb7\xb3\x71\x12\x3c\xb4\xcf\x27\xc8\xad\xcb\x07\xd0\x14\xee\x7e\x67\xe0\xdd\xf4\xde\xac\x89\xff\x73\xd7\xe8\x66\x35\x06\x6a\x8e\xa7\xc7\xc9\x98\x5b\x86\x1e\x4f\x72\xbb\x8c\x73\x3c\x97\x2f\x18\x6e\xc0\x4c\xa6\x79\x78\x6f\xe7\xc8\xfd\x8a\xff\x81\x9f\x59\xf6\xc1\x27\x89\xfe\x4c\x0f\x27\x98\xe0\x66\x01\x0a\x4f\xa7\xa9\x23\xa7\xdd\x09\xee\xb6\x9d\xe7\xd6\xdb\x4f\x36\x49\xca\xa7\xd6\x02\xa7\x6d\xff\x74\x6f\x80\xdd\x21\x8e\x3c\x91\x02\x84\xb5\xfa\xb1\xed\xe8\xd6\x1c\x39\x20\x69\xa8\xc6\xe7\x5d\x47\xb7\xe6\x60\xe3\x9f\xdd\xeb\xc7\x1f\xae\x5d\x70\x2a\x4a\x0a\x9c\x08\x41\x8b\x6c\xe6\x5c\x83\xf6\x46\x3a\x41\x67\xe3\xcd\x90\xb1\x28\x4d\x61\xfe\xb8\xb8\x1d\x08\x45\xf6\xd5\x2c\x87\xd7\x90\x99\x0a\x81\x4a\x75\xc0\x2d\x42\xcd\x9d\xa3\x53\xb4\x32\x45\x41\xbf\x16\x15\xa7\x73\x3e\x9d\x84\x1d\x5d\x12\x60\x8d\xa0\xdb\xeb\xc3\x12\x21\xdc\x2b\xbc\x09\xa1\xb9\x08\x97\x1f\x5f\x62\x95\xc0\x82\xee\x44\x6b\xa9\x14\x70\xe5\xe8\xa6\x21\x54\x93\x87\xd3\x7c\x45\xd7\x0e\x3a\x83\xd7\x56\x6a\x8a\x5d\xa2\xaa\x93\x70\x74\xa2\x94\x77\x94\x29\xd8\x35\xe5\x4c\xa8\x99\xa1\xff\xf6\x9d\x45\x74\xc4\x4e\x66\x5a\xfa\x80\x0c\x0e\xf9\x83\x59\xfa\x4c\x56\xe9\x3c\xea\x16\x1b\xd2\xbc\xdd\x9b\x36\xce\x29\xd5\xed\x1b\x8a\xc6\xe3\x60\xc8\xbe\xb3\x7f\x02\x00\x00\xff\xff\x53\x84\x76\xca\x4a\x0e\x00\x00") func testImagesAgnhostAgnhostGoBytes() ([]byte, error) { return bindataRead( @@ -3425,7 +3425,7 @@ func testImagesAgnhostNetNatClosewaitGo() (*asset, error) { return a, nil } -var _testImagesAgnhostNetexecNetexecGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7b\x6b\x73\xdb\xb8\xd5\xf0\x67\xf2\x57\x9c\x72\x26\x09\x95\xd2\x94\xe2\x6e\xa7\xfb\x6a\xd7\xdd\xf1\xda\x49\xe3\x6e\xea\xf8\xb5\xec\xee\x74\xf2\x64\x5a\x98\x84\x24\x34\x24\xa0\x02\xa0\x2f\x4d\xf3\xdf\x9f\x39\x07\x00\x2f\xba\x38\xf6\x66\x77\xa6\xf3\xb4\x1f\x12\x4b\xe4\xc1\xc1\xb9\xdf\x00\x8d\x9f\xc7\x47\x6a\x75\xa7\xc5\x62\x69\x61\x7f\xf2\xe2\x2b\xb8\x58\x72\xf8\xa1\xb9\xe2\x5a\x72\xcb\x0d\x1c\x36\x76\xa9\xb4\xc9\xe3\xf8\x8d\x28\xb8\x34\xbc\x84\x46\x96\x5c\x83\x5d\x72\x38\x5c\xb1\x62\xc9\xc1\xbf\xc9\xe0\xcf\x5c\x1b\xa1\x24\xec\xe7\x13\x48\x11\x20\xf1\xaf\x92\xd1\x37\xf1\x9d\x6a\xa0\x66\x77\x20\x95\x85\xc6\x70\xb0\x4b\x61\x60\x2e\x2a\x0e\xfc\xb6\xe0\x2b\x0b\x42\x42\xa1\xea\x55\x25\x98\x2c\x38\xdc\x08\xbb\xa4\x4d\x3c\x8a\x3c\xfe\x8b\x47\xa0\xae\x2c\x13\x12\x18\x14\x6a\x75\x07\x6a\xde\x87\x02\x66\xe3\x18\x00\x60\x69\xed\x6a\x3a\x1e\xdf\xdc\xdc\xe4\x8c\xa8\xcc\x95\x5e\x8c\x2b\x07\x65\xc6\x6f\x4e\x8e\x5e\x9e\xce\x5e\xee\xed\xe7\x93\x38\xbe\x94\x15\x37\x06\x34\xff\x47\x23\x34\x2f\xe1\xea\x0e\xd8\x6a\x55\x89\x82\x5d\x55\x1c\x2a\x76\x03\x4a\x03\x5b\x68\xce\x4b\xb0\x0a\xe9\xbc\xd1\xc2\x0a\xb9\xc8\xc0\xa8\xb9\xbd\x61\x9a\xc7\xa5\x30\x56\x8b\xab\xc6\x0e\x04\x14\xa8\x12\x06\xfa\x00\x4a\x02\x93\x90\x1c\xce\xe0\x64\x96\xc0\xf7\x87\xb3\x93\x59\x16\xff\x78\x72\xf1\xfa\xed\xe5\x05\xfc\x78\x78\x7e\x7e\x78\x7a\x71\xf2\x72\x06\x6f\xcf\xe1\xe8\xed\xe9\xf1\xc9\xc5\xc9\xdb\xd3\x19\xbc\x7d\x05\x87\xa7\x7f\x81\x1f\x4e\x4e\x8f\x33\xe0\xc2\x2e\xb9\x06\x7e\xbb\xd2\x48\xbb\xd2\x20\x50\x74\xbc\xcc\xe3\x19\xe7\x83\xcd\xe7\xca\x11\x63\x56\xbc\x10\x73\x51\x40\xc5\xe4\xa2\x61\x0b\x0e\x0b\x75\xcd\xb5\x14\x72\x01\x2b\xae\x6b\x61\x50\x79\x06\x98\x2c\xe3\x4a\xd4\xc2\x32\x4b\xdf\x37\xd8\xc9\xe3\xe7\xe3\x38\x5e\xb1\xe2\x03\x22\x41\x3b\xb9\xe5\x45\x1c\x8b\x7a\xa5\xb4\x85\x34\x8e\x92\x42\x49\xcb\x6f\x6d\x12\x47\x09\x97\x85\x2a\x85\x5c\x8c\xff\x6e\x94\xc4\x07\xf3\x9a\x9e\x0b\xe5\xfe\x1f\x0b\xd5\x58\x51\xe1\x97\x4a\x2d\xf0\x8f\xe4\xd6\xff\x19\xa3\x16\xc3\xe7\x46\x13\x90\x32\xee\xff\x31\x6e\x8a\x1f\x8d\xd5\x85\x92\xd7\xfe\xa3\x90\x0b\x02\x30\x77\xb2\x18\x33\xab\x6a\x41\x40\x56\xd4\x3c\x89\xe3\x28\x59\x08\xbb\x6c\xae\xf2\x42\xd5\x63\x61\x96\xa2\x64\x37\xcc\x32\xdd\x8c\x4d\xe1\x76\xea\xbd\x37\xab\xf9\x8b\xdf\x8c\x0b\x75\xa5\x19\x2e\x45\x2a\x25\xb7\x90\x7c\xf8\xda\xe4\x42\x8d\xd9\x4a\xd4\xac\x58\x0a\xc9\xf5\xdd\x78\xf5\x61\x31\x46\x80\x31\x11\x3f\x8a\xe3\x6b\xa6\x51\x12\xc8\xc0\x19\x4a\x05\x00\x0e\xe0\xeb\xc9\xd7\x93\x38\x6a\xca\xf6\x91\x7b\xf6\x22\x8e\x70\xfb\x0e\x6e\x0f\x9f\x2c\x79\x55\x9d\x31\xbb\xa4\x27\xc9\xf8\x4a\xc8\xb1\x59\x26\x71\x64\xb8\xbe\xe6\xfa\x9c\xb3\xf2\x0e\x0e\xe0\xa9\xe3\xf1\x7b\xa5\xaa\x8f\x93\x4f\x71\x54\x70\x6d\x5f\xa1\x53\xb9\x65\x49\x1c\xad\xb4\xb8\xfe\x81\xdf\xd1\x43\x7a\x32\x8a\xe3\xf1\x18\x8e\xea\xf2\xd4\x69\x0e\xad\xb3\x31\xde\xee\x17\x72\xa9\x8c\x85\x23\xe4\x3a\x27\x2e\x7a\x80\x07\xf0\x94\xc4\x91\x1f\xa9\xba\x66\xb2\xfc\x18\x47\x97\x86\x4f\x01\x20\xf1\x56\x90\x64\x71\x34\x5b\x2a\x6d\xa7\x90\x1c\x69\xce\x30\x84\xbc\xbe\xb8\x38\x4b\x67\xa3\x0c\x2e\x8f\xcf\x32\xb4\x2e\x48\xd5\x0a\x4d\x8b\x55\xd5\xdd\x08\x66\x47\x17\x67\xe0\x98\x32\xce\xeb\xaf\x99\x16\xaa\x31\xc0\x65\xb9\x52\x42\x5a\x83\x58\xdf\x28\xb9\x98\xc2\xdf\x66\x96\x69\x6b\x80\x05\xac\x7e\x25\xba\xd4\x42\x5c\x73\x09\x64\x83\x6d\xf0\x98\xab\xaa\x52\x37\x68\xe1\x2d\xb2\x69\x1c\xef\xc1\x78\x0a\xe7\xdc\x36\x5a\x1a\x02\x43\xd7\xe7\xc6\x3e\x33\x80\x86\x62\x2c\xab\x57\x39\x42\x15\x95\xe0\xd2\x8a\xd5\x2e\xe8\x93\x33\x60\x65\x89\x1e\x48\xe0\xa5\x60\xd5\x14\x02\xdf\xcc\x53\x24\x9b\xfa\x0a\x29\x9c\x87\x85\x06\xa3\x08\x22\x72\xef\x49\xe0\x28\x16\x22\xbd\x31\x48\x6d\xf7\x76\xa5\x95\x55\x85\xaa\xb2\x18\x08\x48\x7b\x42\x18\xfc\x71\xf6\xf6\xb4\xc7\xa9\xe0\x55\x69\x20\xd1\xdc\xac\x14\xc6\xb8\x04\x52\xd3\x14\x05\x37\x66\xde\x54\x61\x6b\x68\x5f\x8f\x08\x5b\xc2\xb5\x56\x1a\x61\x63\x80\x39\x13\x15\x2f\xb7\x80\xe6\x2d\xfb\xc9\xfe\x64\x02\x6f\x7f\x48\xc0\x58\x66\x1b\x03\x85\x2a\x39\x08\x17\x82\x2b\x46\x8b\xdc\x62\xda\x9a\x97\xbc\x44\xba\x93\xaf\x5e\xfc\x0e\x5e\xde\xae\x78\xe1\x62\x0a\xbc\xa2\x9d\x12\x5c\x29\x2c\x94\xa2\xc4\xac\x90\x61\x14\x4b\xbe\x9a\x4c\xe0\x7b\x56\xc2\xb9\x43\x44\x30\x4c\xb6\x71\x3e\xa8\xf1\x99\x81\x15\xd3\xac\xe6\x96\x6b\x13\x03\xda\xb0\x90\xd7\xac\x12\x65\x4e\x29\x6c\x2b\x1c\x30\xcd\xa7\x31\xc0\x1e\x24\x28\xf4\x64\x4a\xa0\x24\x7f\xbb\x64\x68\x36\x55\x05\x57\x1c\x50\x8f\x18\x49\x09\x12\xb5\xe2\x21\x49\x41\xbb\x21\x3d\xef\x1e\x18\x0d\xb4\x25\x03\x59\x2b\x99\x65\xa8\xf9\x2b\x0e\x86\x4b\x44\xa4\x55\xb3\x58\xa2\x5b\xe4\x70\x32\xa7\xc4\xe8\x63\x34\x2f\x33\x14\x0c\xed\xa2\xb9\x69\x2a\x4b\x49\x8d\xb2\xde\xa6\x84\xfa\xba\xb8\xe2\x68\x3e\xce\x48\x3a\x16\xbc\x0d\x05\x36\xfc\x57\xb8\x59\x8a\x62\xd9\xf2\x42\x31\xe0\x66\xc9\x25\xd4\xec\x43\x30\x42\xcf\x53\x0e\xc7\x7c\xce\x9a\xca\xc2\x35\xab\x1a\x3e\x85\x84\x42\x73\x4e\x64\x1d\x16\x98\xbf\x29\x59\xd2\x5b\x13\x5e\x67\x90\x34\x25\xfd\xa1\xf0\xea\xa9\xb1\x5a\x70\xe3\x49\xe9\x7c\x83\x1c\xaf\xbf\x65\x4b\xd7\x8a\xeb\xb9\xd2\x35\x2f\x37\x89\x78\x91\xa0\xdf\x25\x63\x5e\x2c\x55\x32\x74\x52\xe7\x3d\x49\x6d\x16\x09\xa4\x0e\xe2\xbb\xda\x2c\x0e\xf0\x03\x2f\xff\x8a\xcf\x47\x6e\xed\xad\x40\x95\x1d\x55\xca\x78\x02\x7c\x48\x69\x5d\xcb\xa1\x22\xf1\xa2\xcf\x2c\x34\x2b\x38\xfa\x94\x59\x36\xb6\x54\x37\xf2\x1e\x8b\x8b\x23\x32\xb9\x68\x0f\x12\x5c\xef\xb9\xc6\x2d\x1d\xbe\x90\x9b\x57\x5a\xa1\xa7\x6e\x70\x38\xc9\xe1\x10\x23\x18\x66\x65\x10\xd2\xf2\x05\xd7\xf0\x6e\xb2\xf7\x62\xff\x77\xef\x73\x42\x8b\x72\x53\x4d\x30\x3a\x56\xab\x06\xad\xcd\xc9\x13\xad\xed\x86\x09\x4b\xdb\x14\x4a\x4a\x5e\xb8\x94\x6e\x15\x14\xc8\x2f\x5c\xf1\xb9\xd2\x9c\x38\xc1\x82\x06\x88\x9d\x38\x8a\x36\x54\x8a\xae\x03\x0b\x85\xa5\x03\x94\x8d\x76\xa5\x01\x99\xed\xa4\xcf\x80\x53\x1a\xf1\x27\xea\x9a\x97\x82\x59\x5e\xdd\x91\x28\x55\x63\xe3\x28\x6a\x65\x46\xc4\x23\x71\xf7\x53\x1e\x08\xc4\xb0\x8f\x04\x76\x32\xdf\x4a\x62\x1c\xc1\x83\xa9\x24\x9c\x2d\xc2\x3e\xbd\xce\xa8\x96\x9c\x55\x76\xf9\xcf\x9e\x5d\xb5\xd1\xcf\x47\x3c\x6f\x28\x02\x6b\x47\x56\xde\x65\x18\xe8\xf6\x61\xe6\xdc\xf1\x4c\xf3\x42\xc9\x52\xf4\x03\x5e\x0c\xa0\xb0\x6e\xbb\x11\x86\x3b\xab\xe9\x50\x14\x4a\x1a\x51\x72\x2c\x40\x31\x12\x10\xc6\xb0\xd1\xe5\x71\x48\x91\x21\x58\x7a\xea\xef\x38\x86\x16\x8c\x7f\x96\xa4\x8e\x2e\x4f\xb4\x2b\x63\x25\xab\xf9\x9a\x53\x38\x1c\xcf\x0c\x84\xf7\x1d\xf4\xe9\x83\xa1\xa9\x32\x49\xa6\xf0\xf2\x96\x17\x8d\xe5\x03\x77\xa3\x77\xbe\x3a\x48\x28\x9e\x17\x75\x49\x0e\x48\x6f\xbe\x2b\xea\xf2\xc0\xa8\x9a\xef\x15\x1e\x86\xd2\x50\x0c\xeb\x69\x0d\x0b\x48\x26\x64\x88\x42\x21\xb9\xa9\xc6\xae\x1a\x9b\x40\xea\x97\x3f\x33\xe0\x1e\xf5\xb3\x59\xff\x75\x0c\x40\xcf\xa0\xe6\xc6\xb0\x05\xdf\x96\xca\xbc\x8c\xfd\x9a\x5e\xe6\xba\x37\x6f\x49\x65\x83\x38\x9c\x01\xdd\x1f\x43\x3a\x97\x9f\xb8\x65\xcd\xaa\x52\xac\x4c\xa6\xde\x8e\x91\x73\x6a\x86\x5c\x82\x70\x6f\x91\x06\xdf\x6a\xa0\x82\x85\x24\x54\x61\xad\x49\xb0\xbc\x29\x5d\xf1\x63\x7d\x22\xc3\x18\x7b\xfe\x99\x12\xa1\x27\xc5\x35\x29\x57\xfc\x99\x01\xd4\x74\x40\xe9\xd8\x08\x4a\x0a\xf2\xed\xad\xc3\xd4\xbc\x52\x16\xab\x24\x56\x05\xae\xd1\x8e\x9d\xdc\xb1\x71\x3c\xf1\xa1\x9c\x55\x46\x79\xb3\x65\x7d\x8b\xf6\x5b\x09\x59\x8a\x82\x61\x7b\x84\xef\xba\x54\xeb\xca\x90\xb2\x2d\x9a\xba\x92\xce\x6b\xcc\x55\x74\xc9\x43\x4d\x1e\x61\x31\x09\xc0\xb7\xb5\x59\xfc\x7e\x6b\xd6\xa0\x37\x08\x17\xea\xbf\xe4\xf3\x05\x60\x1c\x1f\x96\xce\xd9\xb1\xac\xcd\xd0\x44\x52\x34\x27\x25\x2b\x74\xe3\x11\xec\xed\x61\x12\xdc\x23\xc6\x04\xe6\x08\x63\xfa\x69\xde\x0b\x46\xf6\xeb\x61\x27\x1a\x66\x49\x1a\x59\xec\x25\x41\xea\x72\xb2\x30\xa8\xaa\x20\x06\x60\x66\x2d\x58\xe4\xf1\xdf\xb2\x38\x3a\xd4\x0b\x33\x05\x57\xb8\xff\x89\xdd\x8a\xba\xa9\x4f\xf1\x59\x3a\x19\x65\x71\x74\xde\xc8\x29\x40\xcd\x84\xcc\xe2\x4f\x71\x3c\x6f\x64\x01\x42\x0a\x9b\x8e\xe0\x63\x1c\x75\xc5\x7f\xfe\xaa\x62\x0b\x93\x8e\xf2\x13\x69\xff\xcc\x74\xfa\x34\xb4\x36\x99\x4b\xf6\xc4\x58\x92\x51\x8f\x93\x41\x42\xd5\xcf\x1b\x61\x2c\x97\x80\x50\xc9\x68\x2b\xb2\x19\x75\x6c\x84\x2f\x74\x2e\x19\x24\xb6\x32\x7b\xf8\x75\x0f\x2d\x12\xcb\x07\x6c\x00\xa2\x84\x5a\x98\x81\xed\xc1\xed\x6f\x27\xff\x0f\x10\x14\x1b\x5b\x66\x5d\x42\xc5\xbd\x67\x39\xa4\x47\x87\xf4\x2a\xf3\x25\x64\x86\x6b\x11\x48\x92\x95\xb1\xb9\x45\x53\x75\x82\x46\xb8\xd1\xe7\x69\xec\xf5\x52\x9e\x4c\x7c\xc2\x2c\xdf\xfb\xc0\xef\x1e\x48\xad\x5f\x01\x1f\xf8\x1d\xd4\xcc\x62\x07\xb9\x80\xbd\xbd\x21\xcf\xdb\x29\x09\xa2\xf7\x1d\xa4\x2b\xaf\x7a\x82\x7f\x91\x41\x82\xda\xff\xbc\xdc\x03\xa6\xd0\x77\xfa\x12\x2d\xe0\xda\x43\x4c\x64\x88\x43\x54\x9f\xa8\x75\xec\x5a\x4e\xac\x19\x0d\x60\x30\x1a\x1b\x8b\x79\x5a\xad\xb8\xcf\xba\x7e\xc8\x21\xa4\xfd\xcd\x3e\x9a\xab\x11\x75\x53\x21\xdf\x4c\x7a\x04\x70\xa5\x54\xc5\x99\xcc\x63\x7b\xb7\xe2\x7d\xac\xc6\xea\xa6\xb0\x68\x7f\xd7\x0e\x81\xdf\xd8\x70\x8b\xff\x8c\x8f\x17\x1e\x73\xe7\xb7\x2d\x42\xb2\xe2\x94\xc1\xf3\x0e\x29\x76\x8a\x36\xa5\x4a\x81\xe0\xc8\xbc\xc5\xdc\xd5\x0e\xf8\x39\x72\xb0\xf9\x0c\x19\x39\x41\xe4\xe9\x53\x96\x5f\x67\xf0\x62\x14\x47\x91\xcb\x4f\x71\xf4\x29\xde\x09\x37\x09\xf2\x59\x70\xdb\xe6\x33\xab\x9b\xb6\x41\x72\x14\x1f\x1c\xc0\x8b\xed\x04\x2e\x38\x7a\x1d\x12\x87\xf4\x38\x0c\x5e\x2c\xf9\x1b\xc5\xca\x6e\xb3\x91\xc3\x12\xfc\x15\xbd\x37\x2d\xea\x12\x9e\x0f\xda\xf3\x0c\x98\x5e\x18\x78\xf7\xde\xcd\x45\x88\x63\xcc\x43\x47\x4b\x98\x1e\x60\x91\xcf\xd3\x62\xc9\x64\x5b\x02\xf9\x86\x62\x14\x47\xac\x2c\xcf\x15\xe6\xf6\xd4\xc1\x8f\xe2\x38\x5a\xf8\xe0\x7d\x79\x7c\x36\x23\xa7\x49\xbd\x19\x8e\x48\x8e\xed\x04\xe3\x57\x07\xb0\xf7\x82\x04\x1a\x56\xa0\x21\xf9\x25\x01\x6a\x84\x92\x0c\xb3\x0c\xa4\x86\xc2\x49\xee\xa0\x3e\x1e\x96\xa5\x9e\xc2\xbc\xb6\xf9\x6c\xa5\x85\xb4\xf3\x34\x99\x3e\x29\x93\x0c\x42\xcc\x19\x7d\xa2\x3d\x2b\x2e\xd3\x10\x36\x46\xf0\x7b\x98\xd0\xb6\x6e\x4f\xbf\x1f\xfd\xc9\xc0\xb1\x91\x01\x8a\x2b\x1d\xf9\x9a\xe0\xa3\xd7\x52\x88\x96\xce\xd6\x0f\x65\x49\x8b\x2f\xde\xcc\xd2\x2e\x26\xf5\x3c\x7f\x04\x9f\x90\x7c\xe0\x95\xe1\x9f\xdd\x70\x2b\x6a\xe2\x3e\x28\x6f\x5d\xd6\xb0\x55\x27\xb8\x11\x89\xe8\x35\x93\x65\xc5\x5f\x21\x1f\xc9\x38\xc9\x40\x2b\x65\xdd\x33\x3d\xda\x06\xd2\xa6\xb0\x0c\xdc\xc7\x93\xb3\xfb\xc0\xa9\x93\xca\x00\xff\xdc\x0b\x86\x4d\x93\x17\xe7\x0d\xa9\x25\x3f\xf7\xe3\x82\x1f\xb5\xb0\x28\x01\xcd\xff\x01\xcf\xfd\x9b\xc0\x03\x89\xc5\xe3\x4d\x6f\x08\x26\x88\xca\x49\x75\x73\xa7\x36\xad\x67\x6d\x06\xbf\x8f\x30\x57\x9c\x66\x40\x7f\xef\x03\xf4\xf5\x57\xe6\x4b\xad\xfb\x40\xb1\xc9\x4f\x32\xea\xf5\xef\x03\x0b\xfd\x42\x06\xfe\x53\x07\x3c\x1e\x83\xab\xd4\x96\xee\x91\xd9\xc5\xe9\x69\xc7\xe9\xe9\x67\x39\xf5\x75\x67\xd6\x1a\x4b\x0b\x1e\x6c\x6b\xd3\x32\xbd\x4a\x66\x03\x33\xdd\x6a\x72\x19\xcc\xe5\xc0\x5f\xc8\x06\x17\x2a\x3c\xfb\x48\x51\x11\x7d\xf7\xdb\x3d\x87\x26\x8e\xa2\xc2\xde\x66\x50\x30\x59\xf0\xea\x95\xc4\x77\x7e\x12\x9c\xff\x28\xec\xf2\xc2\xb5\xaa\x69\x78\xf6\x3d\x2b\x3e\x2c\xb4\x6a\x64\x99\x8e\xd0\x16\x72\xdf\xcb\x62\xbc\x2d\xf9\x1c\xd3\xb2\xc7\x94\xe2\x23\xae\x29\x52\x78\x8f\x9a\x79\x6a\xd3\xc2\xde\xe2\xdb\x4a\x2d\xf2\x33\x1f\x2c\xfe\xb0\xde\xa1\xbb\x83\x05\x8e\x69\x1f\xab\xe1\x29\x3c\xb9\x46\x23\xd7\x28\xd9\x48\x99\xfc\xe5\xad\xb0\xa9\xe6\x39\x16\xe8\xe8\x9c\x29\x06\x3c\x31\x07\xbf\xe5\x5c\xa6\xa3\x6f\xe8\xcb\xaf\x0e\x40\x0a\x0a\xcf\xe1\xf5\xc1\x81\x33\xff\x97\x5a\x3b\xa1\x52\x13\x50\x12\x08\xea\x9d\xba\xd8\x46\x5a\x51\xb9\x44\xa5\xb4\x6a\xac\x90\x1c\x0a\x56\x55\x06\xc2\xe6\x48\x48\x64\x78\xc5\x31\xef\x7d\x8a\x23\x4c\x34\xc4\xd3\x2b\x66\x59\x95\x3a\x52\xbb\xa0\xd1\xf3\xfa\x9d\xfe\xb7\xe1\x7d\xf1\x50\x48\x2f\x2f\x60\x8c\xe5\x01\xc6\xd9\x57\x3e\xce\xde\x64\x90\x9c\xbe\xfd\xd1\x0b\x08\xf5\x91\x9f\xaa\x9b\x74\xd4\x99\x54\x2f\x32\x7c\xd1\xce\xed\x40\xe6\x89\xc1\x28\x96\xbf\x52\xba\xfe\x33\xe6\xe2\x94\x66\x36\xa3\x2d\x84\xed\x84\x0c\xb4\xad\x05\xb8\x2f\xa2\xaf\x8d\x9b\x9b\x84\xe8\xfc\x9c\xd7\xca\x72\x4c\x53\xb4\x39\xd5\x2f\x6b\xee\xd3\x2b\x62\xa8\xed\xa3\xf1\x9d\x8d\x23\x6f\xe3\x4e\xb6\xc7\x7e\x46\xd1\x49\xb7\x1f\x1f\x1f\x44\xfd\xc0\x87\xbf\xdd\xdb\x9a\x38\xd0\x06\x5d\x15\x8b\xd6\x3c\x90\x20\x4d\x60\x46\x2d\x59\x3b\xa0\xc2\x90\x69\xe4\x98\xd9\x01\x45\x13\xae\xd1\x36\x5d\xdf\x0a\xfb\x1d\xbe\x3d\x78\x62\x9e\x7a\x5c\xf8\x11\x37\x77\xfa\xef\xb0\x3a\xab\x6b\x49\xc9\xa0\x23\xbe\x23\x33\x0b\x9e\x49\x52\x3c\x63\xda\xf0\x20\xca\x74\xb0\x7c\xd4\xba\xb1\xf7\xdc\xa7\x4f\x87\xf8\xf1\x79\x92\x90\xb7\xae\x9b\x1b\xd3\x8b\xa6\xe6\xd2\xc2\x33\xbf\xe2\x19\xd4\x8d\xb1\xd8\x9e\x33\xa0\x51\xf3\xfa\xa8\x09\x94\x06\x5e\xaf\xec\x5d\x06\x0b\x65\xe1\xc9\x3f\xfe\x47\x26\x6b\xfc\xac\xd5\x92\xc8\xdc\x7d\xcc\x0c\x98\xdf\xe0\xa4\xa7\xd7\x87\xb0\x81\xe0\x3f\x91\x87\x01\x1d\x7d\x06\x50\x71\x2d\x03\xfe\x28\x2e\x3f\xb4\x4a\xa4\x9d\x4a\xb7\x91\xde\x33\xa3\x87\x90\x8e\xe0\x3d\xd2\x37\x66\xa1\xdb\xa9\x1e\x90\xd0\xa7\xba\x6f\xa1\x3f\xba\x31\xf3\x42\xc8\xde\x2c\x50\xc2\x13\x93\x01\x0b\x93\x86\x27\x66\xe7\x08\x35\xc3\xb0\x2e\x7b\x73\x4f\x1a\xb7\x50\xb5\xea\x94\xdb\x9a\xac\x4f\x2e\xa4\xe5\x59\xc5\xf9\x8a\xb4\xeb\x84\x13\xa2\xc2\xc1\x81\x2f\x62\x43\x5e\x08\x19\xa9\xad\xdc\x37\x5d\xfc\x23\xc2\x4c\xc1\x69\xc2\x23\x9a\x86\x0f\x5d\xca\x58\xab\x9e\xbe\x28\x38\xb6\x45\xd9\x20\x38\xa2\xce\x16\xdc\xbe\xf6\xc5\x8b\xcf\x1a\xe3\xb1\xaf\x87\xfc\xc6\xed\xb9\x92\x93\x14\x83\xfd\xc9\x64\xcb\x9c\x33\x0c\x55\x73\x38\xb1\x7e\x74\x84\x2f\x0c\x35\xa0\x06\x98\x47\x0a\xc5\x92\x17\x1f\xc2\xe9\x10\x4d\x1d\x3c\x82\xab\x3b\xb8\x16\xda\x36\x1c\x5f\xba\x63\x11\x77\x6a\x18\x8a\x30\xdf\x26\x0e\x8b\xb5\x2f\x13\x8b\xaf\x00\x7d\x47\xd4\x1d\xd4\xe6\xae\xb5\x43\xc5\xde\xe4\x84\xf2\x35\x67\x25\xd7\xe9\xfe\x64\xb2\x1e\x11\x06\xef\x5d\xb1\x46\x03\xe5\xfe\x3c\xd9\xcd\x21\x7b\x75\xde\xb0\x00\xfc\x22\x26\xda\xba\x72\x14\xb7\x56\x38\xe9\xb6\xea\x55\xc1\x8f\xd9\xc6\x8d\xe8\xdb\x48\xd1\xe8\xca\x45\xba\x54\xe7\x97\xe7\x6f\x02\xe8\xe5\xf9\x09\x5a\xcd\x5a\xb8\x40\xb1\x85\x1a\x4b\x51\xdf\x30\x68\x0d\xdb\x5a\xce\xf5\x87\x5e\x5c\xdf\xb3\xb2\xeb\x67\x7b\x02\x8e\x23\x3a\xef\x9b\x1e\xf8\x53\x83\xfc\xff\x37\x5c\xdf\xa5\xa3\xfc\x0f\xdc\xa6\xee\x58\x70\x14\x47\x34\xa5\xdb\x01\xb3\xf2\x63\x95\x70\x4e\xb5\x03\x2c\x9c\x06\x8e\x00\x3d\xc0\xfb\x44\x1c\xb5\x87\x6f\xbb\xb0\x87\xb3\x3a\x0c\x15\xfa\xee\x8c\x69\x56\xef\x82\x75\x27\x69\xdb\x32\x2e\x6a\xe9\x3b\xdc\x14\xd3\x6c\x40\x49\x9f\x95\xa6\x67\x9e\x3a\x4a\xc8\x88\xc5\xa5\x61\x5c\x91\x75\x47\xce\x6e\xee\x18\xc6\x9d\x19\x04\x7a\x88\x34\xc1\x0d\xd2\xf5\xa2\xed\xc4\xdb\xb7\x6d\x27\x4e\x40\x4e\xe7\x6b\xc9\xa1\x87\xe9\xd3\x23\xd5\xed\x76\x6e\x8f\xd8\x06\x27\xbf\x8f\x33\x85\x40\xb8\x0e\x76\xda\x46\xdf\x7b\xb6\x0f\x5a\xef\x08\x18\x9c\xdb\x3e\x96\x06\x67\x8e\x67\xde\xdc\x24\xb7\xf9\x1f\x95\x90\xaf\xfd\xb3\xd4\x2b\xc4\x4d\x4c\xae\x99\xa6\x69\x33\x81\x61\xf1\xe9\x1e\xd1\x19\xb4\x76\x6d\x99\xf1\x45\x53\x80\x18\x41\xfb\xc8\xf5\x70\x71\x64\x6e\x84\x2d\x96\xe0\xef\xca\xe4\x17\xea\x8d\xba\xe1\x3a\x0d\x4a\x27\x6f\x2d\x98\xe1\x90\x24\x7e\xb4\x9b\x4c\xe3\xa8\xb3\xdb\x03\xff\x10\x9b\x34\xb7\xf3\x81\x0b\x0a\x17\x17\x67\x71\x14\x21\x81\x41\xe5\x48\xc5\x39\x37\xaa\xba\xe6\x17\x47\x67\x48\x4f\x9a\xd8\x62\xe5\x0d\xcd\xcf\x81\xdc\x5e\x4d\xb9\xb9\x0d\x3e\x5b\xdf\xe5\xf2\xf8\x9e\x4d\x2e\x8f\xfd\x26\xee\xd4\x79\x63\x13\x3a\x85\x5e\xdf\xc5\xdf\xfc\x19\x6e\x33\x3b\xda\x60\x06\xe1\xc2\x46\xf8\xda\xed\x44\xab\x07\x5b\x95\xee\x04\x77\x7a\xbf\x19\x35\xd2\x34\x2b\xd4\x2b\x2f\x5b\x7f\xcb\x81\x9c\xb0\xd5\xc4\x83\x8d\xf8\xe1\xce\x13\xee\x9a\x8c\x95\x76\x47\x2c\x64\xc6\x74\xb8\xfb\x13\x9d\x28\x8e\xdc\x41\x4f\x3b\x52\x0c\xe3\x46\x1a\x88\x46\xed\x25\x92\x1d\xef\xd1\x80\xdb\x82\xc0\xbd\x88\x23\xac\xb5\x04\x2e\x98\x7c\x03\x02\xbe\x05\x72\xf9\x6f\x40\xfc\xfa\xd7\x7e\xea\xe0\xe0\x83\x66\x9c\xe6\xd2\x36\x4c\x31\xea\xcb\xa2\x2d\x92\x09\xb4\x1e\x00\x5b\xad\xb8\x2c\x53\xf7\x7d\x57\x42\x41\x24\xbd\x39\x5f\x8f\x99\x16\x41\xfb\x28\x6b\xd9\x18\xb9\xee\xfd\x53\x1c\xb9\x83\x36\xc7\xf9\xea\x9d\xe3\xee\x7d\xe0\xff\x63\x3f\x00\xf9\x95\x6d\xe4\x74\x2b\xdf\xf5\x6e\xf3\xbc\x87\x83\xee\x46\x4e\x3f\x7a\x39\x16\x36\x97\xfa\x9b\x3d\xb8\xce\x7d\xa4\x45\x57\x77\xb6\x97\x86\xff\x6e\x94\xcc\xff\xc4\xb4\x59\xb2\x2a\xf5\x27\xa9\x71\x6f\xb2\x11\xe4\x36\xac\xf1\x1c\xfd\x29\xa1\x1a\x0d\x47\xa1\xf7\x06\x4e\xaf\xe5\x42\x35\x95\x3b\xc3\xa6\x9b\x30\x5a\xb0\x4a\xfc\x73\x77\xe4\xec\x9d\xbf\x86\xb2\xa7\x37\x08\x09\x91\x27\xd5\x5d\xdb\x4d\xc6\x35\x08\x94\x1b\x61\x10\x89\xb5\x9a\x49\x13\x12\xbd\xbf\xdd\x97\xcf\xb8\xbd\x08\xcf\xfd\x5d\x0c\xe3\xce\xba\xf2\xf6\xf9\xc7\x30\xa9\x3c\xa2\x19\x01\x8d\xb9\xe8\xce\x17\x12\xe2\x9e\xa5\x2d\x72\xef\x03\xad\xc8\xbb\x75\x94\xc3\x87\xde\xe9\x2e\xad\x3e\x31\x63\x0a\x04\xc8\x82\x3f\x7d\x72\x03\x32\xe7\x7e\x2e\xc6\x70\x0d\xed\x1e\x39\xcd\x9c\x4e\xca\x8a\x1f\x75\x1d\x4a\xba\x55\x93\x6e\x25\x52\x94\x7f\xaf\xca\x3b\xb7\x92\xa6\x4f\x57\xaa\xbc\x6b\xa9\x74\x97\x32\x73\x2c\x5e\x0f\xab\x2a\x6d\xe1\x47\x83\xc1\x57\xeb\x56\x61\x8e\xee\x0d\x03\x01\x33\x7c\xdb\x7a\x82\x07\x48\x9c\x82\xbb\x81\xcd\x4e\xb1\xf9\x12\xb2\x95\xf9\xc8\x3f\xf0\x22\xc7\x1c\xd5\x0a\xff\x69\xef\x0d\x92\xd3\x2e\x9a\x76\x22\xca\xf0\x79\xe8\x8d\x00\x7e\x0b\xcf\x5d\xbb\x3d\xa3\xa2\x3a\xeb\x13\xe9\x10\x0f\x2c\xec\xf2\xf8\xa7\x18\x18\x2a\xa3\x95\x28\x42\x1e\x7b\x54\x3e\x3f\x49\x51\x79\x25\xa7\xcf\xf1\xb5\x4f\x5f\xdb\x0b\xe0\x9e\x04\xd1\x66\xc8\xc7\xe6\x84\x89\x28\xf4\x97\xf7\x72\x5c\x36\xed\x4d\x37\x31\x40\x3b\x9d\x23\x35\x9d\xba\xaf\x9a\x39\x52\xf5\xee\x3d\x7a\x71\x5b\x01\xc5\xd1\x5f\x43\x50\x25\x70\xaa\xe8\xd3\xab\x66\xfe\x58\x92\xba\x4e\x99\x2e\x30\xf0\xdd\xe4\x45\x4d\xb9\x0a\x0d\x44\x2f\x47\x20\x59\x19\xec\x4f\xbe\xfa\x7a\xe4\x04\x89\x9e\x89\xe6\x78\xcc\x59\x59\x09\xc9\xd3\x6e\x38\x89\x1a\x48\xd7\x34\x3a\xa2\x51\x55\x23\xbb\xe9\x0a\x21\x41\x0c\x69\x6f\xc7\x0d\xbe\xfe\xf5\x2f\xa0\x65\x5d\x2d\xb8\x83\x4b\x6c\x4e\xb1\xa7\x9c\x6b\x55\xc3\x1a\xcb\x7d\x66\x9f\x3d\xb9\x7e\xd6\x67\x77\xe8\x2a\x3d\x52\xde\x4d\xa6\xb4\xf3\x7b\xef\x3a\x7d\xfb\xc3\x7a\xe3\x4b\x0d\x90\xea\x97\xe3\x80\x2c\x14\x2e\x7d\x1b\x24\x88\x50\xda\x3c\xca\x0a\x71\xe5\xbf\x9b\x19\x12\x4d\x8f\xb0\x43\x84\xdf\x69\x88\x2f\x26\xfb\x5f\xfd\xfc\x86\xd8\xdf\xf2\x67\xb2\xc4\x75\xae\x1f\x6e\x8a\x7d\x62\x76\xd9\x62\xff\x54\xed\x31\xdd\x7f\x51\x97\x1b\xd3\xe2\xc1\x55\x31\xc7\x3d\x82\x1d\xb4\xd3\x40\xfa\xb6\x36\x61\xae\x09\xf4\xd3\xd6\xb1\x45\xb8\x5f\xe6\x06\xca\x35\xd6\x09\x45\x5d\xbe\xed\x4d\x8b\xe9\x0a\x84\xdf\x32\x6d\x2f\xd8\x67\x90\xec\x15\x7e\x09\xbe\xbd\x12\x92\xe3\xb2\x55\x43\xc7\x32\x5b\x8b\xb8\x8d\x12\xce\xed\xb4\x59\x85\xf9\xbb\x56\xef\x5d\x03\x8c\x72\xf6\x90\x3b\x6a\xf7\x41\xf5\x46\xcb\xb6\x97\xa6\x1b\x42\x70\x04\x4f\x5d\x0b\xd1\x96\x72\xff\xd7\xca\xbd\xc1\x61\xed\x17\x8d\xb9\xfc\xf9\xaf\x2b\xcf\x9a\x6a\xb7\x82\xe7\x74\xfe\xff\xd7\x56\x88\xce\x20\x5f\x89\x8a\xa7\x49\xb8\xab\xb3\x2d\x28\x21\xd2\xbe\x1e\x93\x4b\x49\x97\x55\xad\xf2\x5c\xd0\x7d\xbb\x1c\x5b\xcf\x7b\xb4\xe4\xf0\xec\x28\xbb\xee\xd7\xd3\xa0\x75\xb9\x6f\x7e\x66\x72\x38\xac\x8c\x82\xa6\x25\xb0\x55\x93\xb7\x24\xaf\xac\x35\xa6\xb6\x68\xef\x44\x5a\xae\x25\xab\xdc\x51\xe8\x4b\x3f\x72\x68\x0f\x33\x83\x06\xb6\x8a\xc2\xdb\xae\x3f\x95\xed\x75\xb8\x2e\x71\x90\xb4\x42\xe2\x88\xa3\xf9\x7a\xad\x7a\xc1\xeb\x95\xd3\x4a\x7b\x3f\x32\x83\xa4\x53\xf3\x23\x75\xa4\x56\x5c\xba\x1b\x99\xd8\x8d\x52\xf2\xf8\x0f\x57\xd5\x16\x89\x7c\x4e\x65\x5d\xa2\x17\x73\x68\x73\xba\x50\xf9\x91\x5a\xdd\xa5\xf3\x8c\xd0\x6d\x1e\xad\xdf\xab\x18\x9f\xc7\xff\xeb\x3b\x3d\x49\xec\xd2\x43\x1c\x5d\x92\xfd\xd3\x5d\xc4\xe9\x01\xcc\x73\x77\x30\xd3\xbf\xdc\xa0\x4c\x7e\xb4\xac\x55\x99\x76\xa0\x19\x4c\x7e\x37\x99\x3c\x52\x2f\x05\x22\xf9\xaf\x5e\x06\x92\xd8\xe9\x1f\x83\x03\x48\xad\x6c\xb8\xf1\x8d\xcb\x69\x49\xa7\x8c\x36\x43\x0d\x8a\x89\xee\xfd\x3d\x47\x46\xee\x97\x68\xe5\xfd\x75\x40\xab\x8d\xc7\x1d\xba\xfc\xf2\x02\xee\x89\xeb\x5e\xa3\xe8\x1f\x70\x9e\xfe\x8c\x07\x9c\xa7\x0f\x3f\xe0\xc4\xfe\x2f\xdc\x7d\x77\x63\x5d\xd3\xde\xc8\x47\x48\x77\xa1\x8e\x7e\xa3\x10\xee\xa8\xb4\xd7\xb6\xf3\xde\x55\xad\x8d\xbb\x95\x20\xa4\xa3\xd0\x61\x3f\x74\x77\xcd\x07\x43\x85\xed\xb3\xef\x2d\x97\x27\xc3\x75\xcd\x51\x1c\x31\x63\xb8\xb6\xa7\xca\xe9\xd6\x99\xa7\xdb\x61\x63\x66\xe1\x6e\x2e\xf6\xa6\x16\x03\x4a\x76\xe0\x72\xe1\xbf\xc3\xb8\xd1\xf0\x6d\xe9\xf2\x87\x5a\xa0\xdf\x79\xfa\xdf\x02\x38\x3c\x89\xbb\x47\x47\x2f\x60\x78\x15\xde\x75\x40\xdc\x18\x58\x69\x75\xc5\x4d\x3e\xf8\x95\x6c\x6e\xb8\x4d\xad\x6e\x78\x4b\x58\xef\x06\xdb\xc0\x83\xbb\xd3\x67\xf7\x5b\x1a\xdc\x72\x03\xd3\x9c\x55\x26\x5c\x12\xa3\x49\x35\xa2\x91\xe1\x76\xe5\xba\x86\x7a\x32\x40\x14\xaf\xb4\xaa\x51\x96\xae\x97\xdd\x2a\xbb\x48\xf3\x82\x8b\x6b\x5e\x5e\xf0\x5b\xeb\x6f\x55\x0c\x4e\x6a\xda\xef\x5a\xd4\xb3\x15\x2b\x78\x1a\x1c\xa2\x99\xbf\x9b\x4c\xe5\xfb\xd1\xc8\xc7\xd6\x01\x26\x6c\xac\xda\x73\x7b\x17\x40\x5b\xe6\x2b\x99\x26\x33\xee\xe4\x89\xb6\x1c\xec\xb6\x9d\x38\x93\x24\xba\xae\xbc\xc7\x15\xb9\xd5\x85\x42\xa6\x7c\x17\x3f\xf4\x90\x35\xc1\x10\x9e\xad\x6c\xfb\xc8\x2e\xe6\x2d\xc3\xaf\x99\x39\xd3\x7c\x2e\x6e\xd3\x3e\x23\x99\xff\xf9\x46\xe2\x14\x18\xad\xe8\x07\xc1\x3d\x39\xcd\x56\x95\xb0\xa7\xeb\x6b\x20\xc9\x60\x7f\x14\xa6\xf8\x08\x9f\x60\x9a\x0a\xfd\x1b\x61\xa1\x13\xc0\x7d\x87\xd6\x81\x1d\x00\xbd\x78\xf7\xe2\x3d\x3e\xfb\x34\x10\xda\x3c\x4d\x5e\x16\x4b\x45\xf7\x43\xae\xe9\xbe\x09\x2e\x79\x84\xa0\x08\xfc\x27\xc8\x67\x43\xad\xed\x5d\xb5\x35\xb5\xce\x3b\xad\x5e\xb1\xe2\x03\x04\xb8\x36\xcb\x0c\xb6\x6e\x47\xcd\x8f\x60\x61\x07\x82\x9f\xc0\x94\x3b\x07\xe9\x18\xeb\x5a\xe9\xb5\x2c\xfb\x41\xaa\x1b\xe9\x27\x6e\xee\x17\x5b\x61\xd9\xb4\xd3\x43\x0f\x4f\x98\x41\xfb\x9f\x10\x14\xf6\xe7\x09\xd5\x5b\x2e\xb5\x7f\x26\x58\xdf\x7b\x80\xb8\x25\x5e\xb7\x77\xe5\x77\x04\xd9\x8a\x22\x33\xd7\xc3\x0d\x5c\xbc\x1e\xcc\xf8\x1e\x1e\xb1\x03\xca\xfb\xe3\xb5\x1b\x86\x6d\x8f\xd7\xbd\x5f\x2f\xfd\xf2\x01\xbb\xff\x53\xa9\xc7\x46\xec\xa2\x9f\xe8\x5a\xbe\xdd\x8f\xf1\x48\x7a\x3b\xe3\x73\xb7\xac\x68\x27\x79\xff\xc6\xf1\x9c\x2c\xfe\x73\x01\xbd\xe8\xc6\xac\x5b\xa3\xf8\x7f\x58\xd8\xde\x14\x07\xc1\xfc\x1c\xc1\x79\x10\x18\x7b\x46\x14\x2e\x14\xbb\x9b\xe0\x3f\x6f\x08\xdf\x64\x67\xc7\xaa\x5f\x20\x50\xfb\x81\xf4\xc3\x23\x35\x79\x66\x17\x80\xba\xd9\xdf\xc0\x22\xbd\xd9\xd0\xcf\x62\xba\xc8\xdd\x76\xb4\xaf\xbd\x63\xa4\x3b\xc2\x9d\x1f\x7d\xb7\xd7\xb2\xda\x1f\xe3\xac\xc3\xf6\x4e\x53\x36\xfb\xa3\xee\x7e\x7e\x42\x0b\x40\x15\x45\xa3\xb5\x9f\xb7\x2b\x3d\xed\x0d\x6b\x3f\xc5\xff\x1b\x00\x00\xff\xff\x3e\xe4\x95\x4d\x6c\x49\x00\x00") +var _testImagesAgnhostNetexecNetexecGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7b\x6b\x73\xdb\xb8\xd5\xf0\x67\xf2\x57\x9c\x72\x26\x09\x95\xd2\x94\xec\x6e\xa7\xfb\x6a\xd7\xdd\xf1\xda\x49\xe3\x6e\xea\xf8\xb5\xec\xee\x74\xf2\x64\x5a\x98\x84\x24\x34\x14\xa0\x05\x40\x5f\x9a\xe6\xbf\x3f\x73\x0e\x00\x5e\x74\x8b\x9d\xa4\xf3\xdc\xfa\x61\x37\x32\x79\x70\x70\xee\x37\x80\xc3\xe7\xf1\xb1\x5a\xde\x6b\x31\x9b\x5b\x38\x18\xed\x7f\x03\x97\x73\x0e\x3f\xd5\xd7\x5c\x4b\x6e\xb9\x81\xa3\xda\xce\x95\x36\x79\x1c\xbf\x16\x05\x97\x86\x97\x50\xcb\x92\x6b\xb0\x73\x0e\x47\x4b\x56\xcc\x39\xf8\x37\x19\xfc\x99\x6b\x23\x94\x84\x83\x7c\x04\x29\x02\x24\xfe\x55\x32\xf8\x2e\xbe\x57\x35\x2c\xd8\x3d\x48\x65\xa1\x36\x1c\xec\x5c\x18\x98\x8a\x8a\x03\xbf\x2b\xf8\xd2\x82\x90\x50\xa8\xc5\xb2\x12\x4c\x16\x1c\x6e\x85\x9d\xd3\x26\x1e\x45\x1e\xff\xc5\x23\x50\xd7\x96\x09\x09\x0c\x0a\xb5\xbc\x07\x35\xed\x42\x01\xb3\x71\x0c\x00\x30\xb7\x76\x39\x1e\x0e\x6f\x6f\x6f\x73\x46\x54\xe6\x4a\xcf\x86\x95\x83\x32\xc3\xd7\xa7\xc7\x2f\xce\x26\x2f\xf6\x0e\xf2\x51\x1c\x5f\xc9\x8a\x1b\x03\x9a\xff\x52\x0b\xcd\x4b\xb8\xbe\x07\xb6\x5c\x56\xa2\x60\xd7\x15\x87\x8a\xdd\x82\xd2\xc0\x66\x9a\xf3\x12\xac\x42\x3a\x6f\xb5\xb0\x42\xce\x32\x30\x6a\x6a\x6f\x99\xe6\x71\x29\x8c\xd5\xe2\xba\xb6\x3d\x01\x05\xaa\x84\x81\x2e\x80\x92\xc0\x24\x24\x47\x13\x38\x9d\x24\xf0\xe3\xd1\xe4\x74\x92\xc5\x3f\x9f\x5e\xbe\x7a\x73\x75\x09\x3f\x1f\x5d\x5c\x1c\x9d\x5d\x9e\xbe\x98\xc0\x9b\x0b\x38\x7e\x73\x76\x72\x7a\x79\xfa\xe6\x6c\x02\x6f\x5e\xc2\xd1\xd9\x5f\xe0\xa7\xd3\xb3\x93\x0c\xb8\xb0\x73\xae\x81\xdf\x2d\x35\xd2\xae\x34\x08\x14\x1d\x2f\xf3\x78\xc2\x79\x6f\xf3\xa9\x72\xc4\x98\x25\x2f\xc4\x54\x14\x50\x31\x39\xab\xd9\x8c\xc3\x4c\xdd\x70\x2d\x85\x9c\xc1\x92\xeb\x85\x30\xa8\x3c\x03\x4c\x96\x71\x25\x16\xc2\x32\x4b\x7f\xaf\xb1\x93\xc7\xcf\x87\x71\xbc\x64\xc5\x7b\x44\x82\x76\x72\xc7\x8b\x38\x16\x8b\xa5\xd2\x16\xd2\x38\x4a\x0a\x25\x2d\xbf\xb3\x49\x1c\x25\x5c\x16\xaa\x14\x72\x36\xfc\xbb\x51\x12\x1f\x4c\x17\xf4\x5c\x28\xf7\xff\xa1\x50\xb5\x15\x15\xfe\x51\xa9\x19\xfe\x23\xb9\xf5\xff\x0c\x51\x8b\xe1\x77\xad\x09\x48\x19\xf7\xff\x21\x6e\x8a\x3f\x8d\xd5\x85\x92\x37\xfe\xa7\x90\x33\x02\x30\xf7\xb2\x18\x32\xab\x16\x82\x80\xac\x58\xf0\x24\x8e\xa3\x64\x26\xec\xbc\xbe\xce\x0b\xb5\x18\x0a\x33\x17\x25\xbb\x65\x96\xe9\x7a\x68\x0a\xb7\x53\xe7\xbd\x59\x4e\xf7\x7f\x33\x2c\xd4\xb5\x66\xb8\x14\xa9\x94\xdc\x42\xf2\xfe\x5b\x93\x0b\x35\x64\x4b\xb1\x60\xc5\x5c\x48\xae\xef\x87\xcb\xf7\xb3\x21\x02\x0c\x89\xf8\x41\x1c\xdf\x30\x8d\x92\x40\x06\xce\x51\x2a\x00\x70\x08\xdf\x8e\xbe\x1d\xc5\x51\x5d\x36\x8f\xdc\xb3\xfd\x38\xc2\xed\x5b\xb8\x3d\x7c\x32\xe7\x55\x75\xce\xec\x9c\x9e\x24\xc3\x6b\x21\x87\x66\x9e\xc4\x91\xe1\xfa\x86\xeb\x0b\xce\xca\x7b\x38\x84\xa7\x8e\xc7\x1f\x95\xaa\x3e\x8c\x3e\xc6\x51\xc1\xb5\x7d\x89\x4e\xe5\x96\x25\x71\xb4\xd4\xe2\xe6\x27\x7e\x4f\x0f\xe9\xc9\x20\x8e\x87\x43\x38\x5e\x94\x67\x4e\x73\x68\x9d\xb5\xf1\x76\x3f\x93\x73\x65\x2c\x1c\x23\xd7\x39\x71\xd1\x01\x3c\x84\xa7\x24\x8e\xfc\x58\x2d\x16\x4c\x96\x1f\xe2\xe8\xca\xf0\x31\x00\x24\xde\x0a\x92\x2c\x8e\x26\x73\xa5\xed\x18\x92\x63\xcd\x19\x86\x90\x57\x97\x97\xe7\xe9\x64\x90\xc1\xd5\xc9\x79\x86\xd6\x05\xa9\x5a\xa2\x69\xb1\xaa\xba\x1f\xc0\xe4\xf8\xf2\x1c\x1c\x53\xc6\x79\xfd\x0d\xd3\x42\xd5\x06\xb8\x2c\x97\x4a\x48\x6b\x10\xeb\x6b\x25\x67\x63\xf8\xdb\xc4\x32\x6d\x0d\xb0\x80\xd5\xaf\x44\x97\x9a\x89\x1b\x2e\x81\x6c\xb0\x09\x1e\x53\x55\x55\xea\x16\x2d\xbc\x41\x36\x8e\xe3\x3d\x18\x8e\xe1\x82\xdb\x5a\x4b\x43\x60\xe8\xfa\xdc\xd8\x67\x06\xd0\x50\x8c\x65\x8b\x65\x8e\x50\x45\x25\xb8\xb4\x62\xb9\x0d\xfa\xf4\x1c\x58\x59\xa2\x07\x12\x78\x29\x58\x35\x86\xc0\x37\xf3\x14\xc9\x7a\x71\x8d\x14\x4e\xc3\x42\x83\x51\x04\x11\xb9\xf7\x24\x70\x14\x0b\x91\x5e\x1b\xa4\xb6\x7d\xbb\xd4\xca\xaa\x42\x55\x59\x0c\x04\xa4\x3d\x21\x0c\xfe\x38\x79\x73\xd6\xe1\x54\xf0\xaa\x34\x90\x68\x6e\x96\x0a\x63\x5c\x02\xa9\xa9\x8b\x82\x1b\x33\xad\xab\xb0\x35\x34\xaf\x07\x84\x2d\xe1\x5a\x2b\x8d\xb0\x31\xc0\x94\x89\x8a\x97\x1b\x40\xf3\x86\xfd\xe4\x60\x34\x82\x37\x3f\x25\x60\x2c\xb3\xb5\x81\x42\x95\x1c\x84\x0b\xc1\x15\xa3\x45\x6e\x31\x6d\xcd\x4b\x5e\x22\xdd\xc9\x37\xfb\xbf\x83\x17\x77\x4b\x5e\xb8\x98\x02\x2f\x69\xa7\x04\x57\x0a\x0b\xa5\x28\x31\x2b\x64\x18\xc5\x92\x6f\x46\x23\xf8\x91\x95\x70\xe1\x10\x11\x0c\x93\x4d\x9c\x0f\x6a\x7c\x66\x60\xc9\x34\x5b\x70\xcb\xb5\x89\x01\x6d\x58\xc8\x1b\x56\x89\x32\xa7\x14\xb6\x11\x0e\x98\xe6\xe3\x18\x60\x0f\x12\x14\x7a\x32\x26\x50\x92\xbf\x9d\x33\x34\x9b\xaa\x82\x6b\x0e\xa8\x47\x8c\xa4\x04\x89\x5a\xf1\x90\xa4\xa0\xed\x90\x9e\x77\x0f\x8c\x06\xda\x90\x81\xac\x95\xcc\x32\xd4\xfc\x35\x07\xc3\x25\x22\xd2\xaa\x9e\xcd\xd1\x2d\x72\x38\x9d\x52\x62\xf4\x31\x9a\x97\x19\x0a\x86\x76\xd1\xdc\xd4\x95\xa5\xa4\x46\x59\x6f\x5d\x42\x5d\x5d\x5c\x73\x34\x1f\x67\x24\x2d\x0b\xde\x86\x02\x1b\xfe\x4f\xb8\x9d\x8b\x62\xde\xf0\x42\x31\xe0\x76\xce\x25\x2c\xd8\xfb\x60\x84\x9e\xa7\x1c\x4e\xf8\x94\xd5\x95\x85\x1b\x56\xd5\x7c\x0c\x09\x85\xe6\x9c\xc8\x3a\x2a\x30\x7f\x53\xb2\xa4\xb7\x26\xbc\xce\x20\xa9\x4b\xfa\x87\xc2\xab\xa7\xc6\x6a\xc1\x8d\x27\xa5\xf5\x0d\x72\xbc\xee\x96\x0d\x5d\x4b\xae\xa7\x4a\x2f\x78\xb9\x4e\xc4\x7e\x82\x7e\x97\x0c\x79\x31\x57\x49\xdf\x49\x9d\xf7\x24\x0b\x33\x4b\x20\x75\x10\x3f\x2c\xcc\xec\x10\x7f\xf0\xf2\xaf\xf8\x7c\xe0\xd6\xde\x09\x54\xd9\x71\xa5\x8c\x27\xc0\x87\x94\xc6\xb5\x1c\x2a\x12\x2f\xfa\xcc\x4c\xb3\x82\xa3\x4f\x99\x79\x6d\x4b\x75\x2b\x77\x58\x5c\x1c\x91\xc9\x45\x7b\x90\xe0\x7a\xcf\x35\x6e\xe9\xf0\x85\xdc\xbc\xd4\x0a\x3d\x75\x8d\xc3\x51\x0e\x47\x18\xc1\x30\x2b\x83\x90\x96\xcf\xb8\x86\xb7\xa3\xbd\xfd\x83\xdf\xbd\xcb\x09\x2d\xca\x4d\xd5\xc1\xe8\xd8\x42\xd5\x68\x6d\x4e\x9e\x68\x6d\xb7\x4c\x58\xda\xa6\x50\x52\xf2\xc2\xa5\x74\xab\xa0\x40\x7e\xe1\x9a\x4f\x95\xe6\xc4\x09\x16\x34\x40\xec\xc4\x51\xb4\xa6\x52\x74\x1d\x98\x29\x2c\x1d\xa0\xac\xb5\x2b\x0d\xc8\x6c\x47\x5d\x06\x9c\xd2\x88\x3f\xb1\x58\xf0\x52\x30\xcb\xab\x7b\x12\xa5\xaa\x6d\x1c\x45\x8d\xcc\x88\x78\x24\x6e\x37\xe5\x81\x40\x0c\xfb\x48\x60\x2b\xf3\x8d\x24\xc6\x11\x3c\x98\x4a\xc2\xd9\x20\xec\xd2\xeb\x8c\x6a\xce\x59\x65\xe7\xff\xe8\xd8\x55\x13\xfd\x7c\xc4\xf3\x86\x22\xb0\x76\x64\xe5\x7d\x86\x81\xee\x00\x26\xce\x1d\xcf\x35\x2f\x94\x2c\x45\x37\xe0\xc5\x00\x0a\xeb\xb6\x5b\x61\xb8\xb3\x9a\x16\x45\xa1\xa4\x11\x25\xc7\x02\x14\x23\x01\x61\x0c\x1b\x5d\x9d\x84\x14\x19\x82\xa5\xa7\xfe\x9e\x63\x68\xc1\xf8\x67\x49\xea\xe8\xf2\x44\xbb\x32\x56\xb2\x05\x5f\x71\x0a\x87\xe3\x99\x81\xf0\xbe\x85\x3e\x7b\x30\x34\x55\x26\xc9\x18\x5e\xdc\xf1\xa2\xb6\xbc\xe7\x6e\xf4\xce\x57\x07\x09\xc5\xf3\x62\x51\x92\x03\xd2\x9b\x1f\x8a\x45\x79\x68\xd4\x82\xef\x15\x1e\x86\xd2\x50\x0c\xab\x69\x0d\x0b\x48\x26\x64\x88\x42\x21\xb9\xa9\xda\x2e\x6b\x9b\x40\xea\x97\x3f\x33\xe0\x1e\x75\xb3\x59\xf7\x75\x0c\x40\xcf\x60\xc1\x8d\x61\x33\xbe\x29\x95\x79\x19\xfb\x35\x9d\xcc\xb5\x33\x6f\x49\x65\x83\x38\x9c\x01\xed\x8e\x21\xad\xcb\x8f\xdc\xb2\x7a\x59\x29\x56\x26\x63\x6f\xc7\xc8\x39\x35\x43\x2e\x41\xb8\xb7\x48\x83\x6f\x35\x50\xc1\x42\x12\xaa\xb0\xd6\x24\x58\xde\x94\xae\xf8\xb1\x3e\x91\x61\x8c\xbd\xf8\x44\x89\xd0\x91\xe2\x8a\x94\x2b\xfe\xcc\x00\x6a\x3a\xa0\x74\x6c\x04\x25\x05\xf9\x76\xd6\x61\x6a\x5e\x2a\x8b\x55\x12\xab\x02\xd7\x68\xc7\x4e\xee\xd8\x38\x9e\xfa\x50\xce\x2a\xa3\xbc\xd9\xb2\xae\x45\xfb\xad\x84\x2c\x45\xc1\xb0\x3d\xc2\x77\x6d\xaa\x75\x65\x48\xd9\x14\x4d\x6d\x49\xe7\x35\xe6\x2a\xba\xe4\xa1\x26\x8f\xb0\x98\x04\xe0\xfb\x85\x99\xfd\x7e\x63\xd6\xa0\x37\x08\x17\xea\xbf\xe4\xd3\x05\x60\x1c\x1f\x95\xce\xd9\xb1\xac\xcd\xd0\x44\x52\x34\x27\x25\x2b\x74\xe3\x01\xec\xed\x61\x12\xdc\x23\xc6\x04\xe6\x08\x63\xba\x69\xde\x0b\x46\x76\xeb\x61\x27\x1a\x66\x49\x1a\x59\xec\x25\x41\xea\x72\xb2\x30\xa8\xaa\x20\x06\x60\x66\x25\x58\xe4\xf1\xdf\xb2\x38\x3a\xd2\x33\x33\x06\x57\xb8\xff\x89\xdd\x89\x45\xbd\x38\xc3\x67\xe9\x68\x90\xc5\xd1\x45\x2d\xc7\x00\x0b\x26\x64\x16\x7f\x8c\xe3\x69\x2d\x0b\x10\x52\xd8\x74\x00\x1f\xe2\xa8\x2d\xfe\xf3\x97\x15\x9b\x99\x74\x90\x9f\x4a\xfb\x67\xa6\xd3\xa7\xa1\xb5\xc9\x5c\xb2\x27\xc6\x92\x8c\x7a\x9c\x0c\x12\xaa\x7e\x5e\x0b\x63\xb9\x04\x84\x4a\x06\x1b\x91\x4d\xa8\x63\x23\x7c\xa1\x73\xc9\x20\xb1\x95\xd9\xc3\x3f\xf7\xd0\x22\xb1\x7c\xc0\x06\x20\x4a\xa8\x85\xe9\xd9\x1e\xdc\xfd\x76\xf4\xff\x00\x41\xb1\xb1\x65\xd6\x25\x54\xdc\x7b\x92\x43\x7a\x7c\x44\xaf\x32\x5f\x42\x66\xb8\x16\x81\x24\x59\x19\x9b\x5a\x34\x55\x27\x68\x84\x1b\x7c\x9a\xc6\x4e\x2f\xe5\xc9\xc4\x27\xcc\xf2\xbd\xf7\xfc\xfe\x81\xd4\xfa\x15\xf0\x9e\xdf\xc3\x82\x59\xec\x20\x67\xb0\xb7\xd7\xe7\x79\x33\x25\x41\xf4\xbe\x83\x74\xe5\x55\x47\xf0\xfb\x19\x24\xa8\xfd\x4f\xcb\x3d\x60\x0a\x7d\xa7\x2f\xd1\x02\xae\x3d\xc4\x44\x86\xd8\x47\xf5\x91\x5a\xc7\xb6\xe5\xc4\x9a\xd1\x00\x06\xa3\xa1\xb1\x98\xa7\xd5\x92\xfb\xac\xeb\x87\x1c\x42\xda\xdf\x1c\xa0\xb9\x1a\xb1\xa8\x2b\xe4\x9b\x49\x8f\x00\xae\x95\xaa\x38\x93\x79\x6c\xef\x97\xbc\x8b\xd5\x58\x5d\x17\x16\xed\xef\xc6\x21\xf0\x1b\x1b\x6e\xf1\x3f\xe3\xe3\x85\xc7\xdc\xfa\x6d\x83\x90\xac\x38\x65\xf0\xbc\x45\x8a\x9d\xa2\x4d\xa9\x52\x20\x38\x32\x6f\x31\x75\xb5\x03\xfe\x8e\x1c\x6c\x3e\x41\x46\x4e\x11\x79\xfa\x94\xe5\x37\x19\xec\x0f\xe2\x28\x72\xf9\x29\x8e\x3e\xc6\x5b\xe1\x46\x41\x3e\x33\x6e\x9b\x7c\x66\x75\xdd\x34\x48\x8e\xe2\xc3\x43\xd8\xdf\x4c\xe0\x8c\xa3\xd7\x21\x71\x48\x8f\xc3\xe0\xc5\x92\xbf\x56\xac\x6c\x37\x1b\x38\x2c\xc1\x5f\xd1\x7b\xd3\x62\x51\xc2\xf3\x5e\x7b\x9e\x01\xd3\x33\x03\x6f\xdf\xb9\xb9\x08\x71\x8c\x79\xe8\x78\x0e\xe3\x43\x2c\xf2\x79\x5a\xcc\x99\x6c\x4a\x20\xdf\x50\x0c\xe2\x88\x95\xe5\x85\xc2\xdc\x9e\x3a\xf8\x41\x1c\x47\x33\x1f\xbc\xaf\x4e\xce\x27\xe4\x34\xa9\x37\xc3\x01\xc9\xb1\x99\x60\xfc\xea\x10\xf6\xf6\x49\xa0\x61\x05\x1a\x92\x5f\x12\xa0\x06\x28\xc9\x30\xcb\x40\x6a\x28\x9c\xe4\x0e\xea\xc3\x51\x59\xea\x31\x4c\x17\x36\x9f\x2c\xb5\x90\x76\x9a\x26\xe3\x27\x65\x92\x41\x88\x39\x83\x8f\xb4\x67\xc5\x65\x1a\xc2\xc6\x00\x7e\x0f\x23\xda\xd6\xed\xe9\xf7\xa3\x7f\x32\x70\x6c\x64\x80\xe2\x4a\x07\xbe\x26\xf8\xe0\xb5\x14\xa2\xa5\xb3\xf5\x23\x59\xd2\xe2\xcb\xd7\x93\xb4\x8d\x49\x1d\xcf\x1f\xc0\x47\x24\x1f\x78\x65\xf8\x27\x37\xdc\x88\x9a\xb8\x0f\xca\x5b\x95\x35\x6c\xd4\x09\x6e\x44\x22\x7a\xc5\x64\x59\xf1\x97\xc8\x47\x32\x4c\x32\xd0\x4a\x59\xf7\x4c\x0f\x36\x81\x34\x29\x2c\x03\xf7\xf3\xf4\x7c\x17\x38\x75\x52\x19\xe0\x3f\x3b\xc1\xb0\x69\xf2\xe2\xbc\x25\xb5\xe4\x17\x7e\x5c\xf0\xb3\x16\x16\x25\xa0\xf9\x2f\xf0\xdc\xbf\x09\x3c\x90\x58\x3c\xde\xf4\x96\x60\x82\xa8\x9c\x54\xd7\x77\x6a\xd2\x7a\xd6\x64\xf0\x5d\x84\xb9\xe2\x34\x03\xfa\x77\x17\xa0\xaf\xbf\x32\x5f\x6a\xed\x02\xc5\x26\x3f\xc9\xa8\xd7\xdf\x05\x16\xfa\x85\x0c\xfc\xaf\x16\x78\x38\x04\x57\xa9\xcd\xdd\x23\xb3\x8d\xd3\xb3\x96\xd3\xb3\x4f\x72\xea\xeb\xce\xac\x31\x96\x06\x3c\xd8\xd6\xba\x65\x7a\x95\x4c\x7a\x66\xba\xd1\xe4\x32\x98\xca\x9e\xbf\x90\x0d\xce\x54\x78\xf6\x81\xa2\x22\xfa\xee\xf7\x7b\x0e\x4d\x1c\x45\x85\xbd\xcb\xa0\x60\xb2\xe0\xd5\x4b\x89\xef\xfc\x24\x38\xff\x59\xd8\xf9\xa5\x6b\x55\xd3\xf0\xec\x47\x56\xbc\x9f\x69\x55\xcb\x32\x1d\xa0\x2d\xe4\xbe\x97\xc5\x78\x5b\xf2\x29\xa6\x65\x8f\x29\xc5\x47\x5c\x53\xa4\xf0\x1e\x35\xf1\xd4\xa6\x85\xbd\xc3\xb7\x95\x9a\xe5\xe7\x3e\x58\xfc\x61\xb5\x43\x77\x07\x0b\x1c\xd3\x3e\x56\xc3\x63\x78\x72\x83\x46\xae\x51\xb2\x91\x32\xf9\x8b\x3b\x61\x53\xcd\x73\x2c\xd0\xd1\x39\x53\x0c\x78\x62\x0a\x7e\xcb\xa9\x4c\x07\xdf\xd1\x1f\xbf\x3a\x04\x29\x28\x3c\x87\xd7\x87\x87\xce\xfc\x5f\x68\xed\x84\x4a\x4d\x40\x49\x20\xa8\x77\xea\x62\x6b\x69\x45\xe5\x12\x95\xd2\xaa\xb6\x42\x72\x28\x58\x55\x19\x08\x9b\x23\x21\x91\xe1\x15\xc7\xbc\xf7\x31\x8e\x30\xd1\x10\x4f\x2f\x99\x65\x55\xea\x48\x6d\x83\x46\xc7\xeb\xb7\xfa\xdf\x9a\xf7\xc5\x7d\x21\xbd\xb8\x84\x21\x96\x07\x18\x67\x5f\xfa\x38\x7b\x9b\x41\x72\xf6\xe6\x67\x2f\x20\xd4\x47\x7e\xa6\x6e\xd3\x41\x6b\x52\x9d\xc8\xf0\x45\x3b\x37\x03\x99\x27\x06\xa3\x58\xfe\x52\xe9\xc5\x9f\x31\x17\xa7\x34\xb3\x19\x6c\x20\x6c\x2b\x64\xa0\x6d\x25\xc0\x7d\x11\x7d\x4d\xdc\x5c\x27\x44\xe7\x17\x7c\xa1\x2c\xc7\x34\x45\x9b\x53\xfd\xb2\xe2\x3e\x9d\x22\x86\xda\x3e\x1a\xdf\xd9\x38\xf2\x36\xee\x64\x7b\xe2\x67\x14\xad\x74\xbb\xf1\xf1\x41\xd4\xf7\x7c\xf8\xfb\xbd\x8d\x89\x03\x6d\xd0\x55\xb1\x68\xcd\x3d\x09\xd2\x04\x66\xd0\x90\xb5\x05\x2a\x0c\x99\x06\x8e\x99\x2d\x50\x34\xe1\x1a\x6c\xd2\xf5\x9d\xb0\x3f\xe0\xdb\xc3\x27\xe6\xa9\xc7\x85\x3f\x71\x73\xa7\xff\x16\xab\xb3\xba\x86\x94\x0c\x5a\xe2\x5b\x32\xb3\xe0\x99\x24\xc5\x73\xa6\x0d\x0f\xa2\x4c\x7b\xcb\x07\x8d\x1b\x7b\xcf\x7d\xfa\xb4\x8f\x1f\x9f\x27\x09\x79\xeb\xaa\xb9\x31\x3d\xab\x17\x5c\x5a\x78\xe6\x57\x3c\x83\x45\x6d\x2c\xb6\xe7\x0c\x68\xd4\xbc\x3a\x6a\x02\xa5\x81\x2f\x96\xf6\x3e\x83\x99\xb2\xf0\xe4\x97\xff\x90\xc9\x0a\x3f\x2b\xb5\x24\x32\xb7\x8b\x99\x1e\xf3\x6b\x9c\x74\xf4\xfa\x10\x36\x10\xfc\x33\x79\xe8\xd1\xd1\x65\x00\x15\xd7\x30\xe0\x8f\xe2\xf2\x23\xab\x44\xda\xaa\x74\x13\xe9\x1d\x33\x7a\x08\xe9\x08\xde\x21\x7d\x6d\x16\xba\x99\xea\x1e\x09\x5d\xaa\xbb\x16\xfa\xb3\x1b\x33\xcf\x84\xec\xcc\x02\x25\x3c\x31\x19\xb0\x30\x69\x78\x62\xb6\x8e\x50\x33\x0c\xeb\xb2\x33\xf7\xa4\x71\x0b\x55\xab\x4e\xb9\x8d\xc9\xfa\xe4\x42\x5a\x9e\x54\x9c\x2f\x49\xbb\x4e\x38\x21\x2a\x1c\x1e\xfa\x22\x36\xe4\x85\x90\x91\x9a\xca\x7d\xdd\xc5\x3f\x20\xcc\x18\x9c\x26\x3c\xa2\x71\xf8\xd1\xa6\x8c\x95\xea\xe9\x8b\x82\x63\x53\x94\xf5\x82\x23\xea\x6c\xc6\xed\x2b\x5f\xbc\xf8\xac\x31\x1c\xfa\x7a\xc8\x6f\xdc\x9c\x2b\x39\x49\x31\x38\x18\x8d\x36\xcc\x39\xc3\x50\x35\x87\x53\xeb\x47\x47\xf8\xc2\x50\x03\x6a\x80\x79\xa4\x50\xcc\x79\xf1\x3e\x9c\x0e\xd1\xd4\xc1\x23\xb8\xbe\x87\x1b\xa1\x6d\xcd\xf1\xa5\x3b\x16\x71\xa7\x86\xa1\x08\xf3\x6d\x62\xbf\x58\xfb\x32\xb1\xf8\x0a\xd0\x77\x44\xed\x41\x6d\xee\x5a\x3b\x54\xec\x6d\x4e\x28\x5f\x71\x56\x72\x9d\x1e\x8c\x46\xab\x11\xa1\xf7\xde\x15\x6b\x34\x50\xee\xce\x93\xdd\x1c\xb2\x53\xe7\xf5\x0b\xc0\x2f\x62\xa2\xa9\x2b\x07\x71\x63\x85\xa3\x76\xab\x4e\x15\xfc\x98\x6d\xdc\x88\xbe\x89\x14\xb5\xae\x5c\xa4\x4b\x75\x7e\x75\xf1\x3a\x80\x5e\x5d\x9c\xa2\xd5\xac\x84\x0b\x14\x5b\xa8\xb1\x14\xf5\x0d\xbd\xd6\xb0\xa9\xe5\x5c\x7f\xe8\xc5\xf5\x23\x2b\xdb\x7e\xb6\x23\xe0\x38\xa2\xf3\xbe\xf1\xa1\x3f\x35\xc8\xff\x7f\xcd\xf5\x7d\x3a\xc8\xff\xc0\x6d\xea\x8e\x05\x07\x71\x44\x53\xba\x2d\x30\x4b\x3f\x56\x09\xe7\x54\x5b\xc0\xc2\x69\xe0\x00\xd0\x03\xbc\x4f\xc4\x51\x73\xf8\xb6\x0d\x7b\x38\xab\xc3\x50\xa1\xef\xcf\x99\x66\x8b\x6d\xb0\xee\x24\x6d\x53\xc6\x45\x2d\xfd\x80\x9b\x62\x9a\x0d\x28\xe9\xb7\xd2\xf4\xcc\x53\x47\x09\x19\xb1\xb8\x34\x8c\x2b\xb2\xf6\xc8\xd9\xcd\x1d\xc3\xb8\x33\x83\x40\x0f\x91\x26\xb8\x41\xba\xf6\x9b\x4e\xbc\x79\xdb\x74\xe2\x04\xe4\x74\xbe\x92\x1c\x3a\x98\x3e\x3e\x52\xdd\x6e\xe7\xe6\x88\xad\x77\xf2\xfb\x38\x53\x08\x84\xeb\x60\xa7\x4d\xf4\xdd\xb1\x7d\xd0\x7a\x4b\x40\xef\xdc\xf6\xb1\x34\x38\x73\x3c\xf7\xe6\x26\xb9\xcd\xff\xa8\x84\x7c\xe5\x9f\xa5\x5e\x21\x6e\x62\x72\xc3\x34\x4d\x9b\x09\x0c\x8b\x4f\xf7\x88\xce\xa0\xb5\x6b\xcb\x8c\x2f\x9a\x02\xc4\x00\x9a\x47\xae\x87\x8b\x23\x73\x2b\x6c\x31\x07\x7f\x57\x26\xbf\x54\xaf\xd5\x2d\xd7\x69\x50\x3a\x79\x6b\xc1\x0c\x87\x24\xf1\xa3\xdd\x64\x1c\x47\xad\xdd\x1e\xfa\x87\xd8\xa4\xb9\x9d\x0f\x5d\x50\xb8\xbc\x3c\x8f\xa3\x08\x09\x0c\x2a\x47\x2a\x2e\xb8\x51\xd5\x0d\xbf\x3c\x3e\x47\x7a\xd2\xc4\x16\x4b\x6f\x68\x7e\x0e\xe4\xf6\xaa\xcb\xf5\x6d\xf0\xd9\xea\x2e\x57\x27\x3b\x36\xb9\x3a\xf1\x9b\xb8\x53\xe7\xb5\x4d\xe8\x14\x7a\x75\x17\x7f\xf3\xa7\xbf\xcd\xe4\x78\x8d\x19\x84\x0b\x1b\xe1\x6b\xb7\x13\xad\xee\x6d\x55\xba\x13\xdc\xf1\x6e\x33\xaa\xa5\xa9\x97\xa8\x57\x5e\x36\xfe\x96\x03\x39\x61\xa3\x89\x07\x1b\xf1\xc3\x9d\x27\xdc\x35\x19\x2a\xed\x8e\x58\xc8\x8c\xe9\x70\xf7\x33\x9d\x28\x8e\xdc\x41\x4f\x33\x52\x0c\xe3\x46\x1a\x88\x46\xcd\x25\x92\x2d\xef\xd1\x80\x9b\x82\xc0\xbd\x88\x23\xac\xb5\x04\x2e\x18\x7d\x07\x02\xbe\x07\x72\xf9\xef\x40\xfc\xfa\xd7\x7e\xea\xe0\xe0\x83\x66\x9c\xe6\xd2\x26\x4c\x31\xea\xcb\xa2\x0d\x92\x09\xb4\x1e\x02\x5b\x2e\xb9\x2c\x53\xf7\xf7\xb6\x84\x82\x48\x3a\x73\xbe\x0e\x33\x0d\x82\xe6\x51\xd6\xb0\x31\x70\xdd\xfb\xc7\x38\x72\x07\x6d\x8e\xf3\xe5\x5b\xc7\xdd\xbb\xc0\xff\x87\x6e\x00\xf2\x2b\x9b\xc8\xe9\x56\xbe\xed\xdc\xe6\x79\x07\x87\xed\x8d\x9c\x6e\xf4\x72\x2c\xac\x2f\xf5\x37\x7b\x70\x9d\xfb\x49\x8b\xae\xef\x6d\x27\x0d\xff\xdd\x28\x99\xff\x89\x69\x33\x67\x55\xea\x4f\x52\xe3\xce\x64\x23\xc8\xad\x5f\xe3\x39\xfa\x53\x42\x35\xe8\x8f\x42\x77\x06\x4e\xaf\xe5\x42\xd5\x95\x3b\xc3\xa6\x9b\x30\x5a\xb0\x4a\xfc\x63\x7b\xe4\xec\x9c\xbf\x86\xb2\xa7\x33\x08\x09\x91\x27\xd5\x6d\xdb\x4d\xc6\xd5\x0b\x94\x6b\x61\x10\x89\xb5\x9a\x49\x13\x12\xbd\xbf\xdd\x97\x4f\xb8\xbd\x0c\xcf\xfd\x5d\x0c\xe3\xce\xba\xf2\xe6\xf9\x87\x30\xa9\x3c\xa6\x19\x01\x8d\xb9\xe8\xce\x17\x12\xe2\x9e\xa5\x0d\x72\xef\x03\x8d\xc8\xdb\x75\x94\xc3\xfb\xde\xe9\x2e\xad\x3e\x31\x43\x0a\x04\xc8\x82\x3f\x7d\x72\x03\x32\xe7\x7e\x2e\xc6\x70\x0d\xcd\x1e\x39\xcd\x9c\x4e\xcb\x8a\x1f\xb7\x1d\x4a\xba\x51\x93\x6e\x25\x52\x94\xff\xa8\xca\x7b\xb7\x92\xa6\x4f\xd7\xaa\xbc\x6f\xa8\x74\x97\x32\x73\x2c\x5e\x8f\xaa\x2a\x6d\xe0\x07\xbd\xc1\x57\xe3\x56\x61\x8e\xee\x0d\x03\x01\x33\x7c\xdb\x78\x82\x07\x48\x9c\x82\xdb\x81\xcd\x56\xb1\xf9\x12\xb2\x91\xf9\xc0\x3f\xf0\x22\xc7\x1c\xd5\x08\xff\x69\xe7\x0d\x92\xd3\x2c\x1a\xb7\x22\xca\xf0\x79\xe8\x8d\x00\x7e\x0b\xcf\x5d\xbb\x3d\xa1\xa2\x3a\xeb\x12\xe9\x10\xf7\x2c\xec\xea\xe4\x73\x0c\x0c\x95\xd1\x48\x14\x21\x4f\x3c\x2a\x9f\x9f\xa4\xa8\xbc\x92\xd3\xe7\xf8\xda\xa7\xaf\xcd\x05\x70\x47\x82\x68\x33\xe4\x63\x53\xc2\x44\x14\xfa\xcb\x7b\x39\x2e\x1b\x77\xa6\x9b\x18\xa0\x9d\xce\x91\x9a\x56\xdd\xd7\xf5\x14\xa9\x7a\xfb\x0e\xbd\xb8\xa9\x80\xe2\xe8\xaf\x21\xa8\x12\x38\x55\xf4\xe9\x75\x3d\x7d\x2c\x49\x6d\xa7\x4c\x17\x18\xf8\x76\xf2\xa2\xba\x5c\x86\x06\xa2\x93\x23\x90\xac\x0c\x0e\x46\xdf\x7c\x3b\x70\x82\x44\xcf\x44\x73\x3c\xe1\xac\xac\x84\xe4\x69\x3b\x9c\x44\x0d\xa4\x2b\x1a\x1d\xd0\xa8\xaa\x96\xed\x74\x85\x90\x20\x86\xb4\xb3\xe3\x1a\x5f\xff\xfc\x27\xd0\xb2\xb6\x16\xdc\xc2\x25\x36\xa7\xd8\x53\x4e\xb5\x5a\xc0\x0a\xcb\x5d\x66\x9f\x3d\xb9\x79\xd6\x65\xb7\xef\x2a\x1d\x52\xde\x8e\xc6\xb4\xf3\x3b\xef\x3a\x5d\xfb\xc3\x7a\xe3\x4b\x0d\x90\xea\x97\x93\x80\x2c\x14\x2e\x5d\x1b\x24\x88\x50\xda\x3c\xca\x0a\x71\xe5\x7f\x37\x33\x24\x9a\x1e\x61\x87\x08\xbf\xd5\x10\xf7\x47\x07\xdf\x7c\x7d\x43\xec\x6e\xf9\x95\x2c\x71\x95\xeb\x87\x9b\x62\x97\x98\x6d\xb6\xd8\x3d\x55\x7b\x4c\xf7\x5f\x2c\xca\xb5\x69\x71\xef\xaa\x98\xe3\x1e\xc1\x0e\x9b\x69\x20\xfd\xb5\x32\x61\x5e\x10\xe8\xc7\x8d\x63\x8b\x70\xbf\xcc\x0d\x94\x17\x58\x27\x14\x8b\xf2\x4d\x67\x5a\x4c\x57\x20\xfc\x96\x69\x73\xc1\x3e\x83\x64\xaf\xf0\x4b\xf0\xed\xb5\x90\x1c\x97\x2d\x6b\x3a\x96\xd9\x58\xc4\xad\x95\x70\x6e\xa7\xf5\x2a\xcc\xdf\xb5\x7a\xe7\x1a\x60\x94\xb3\x87\xdc\x52\xbb\xf7\xaa\x37\x5a\xb6\xb9\x34\x5d\x13\x82\x23\x78\xec\x5a\x88\xa6\x94\xfb\xdf\x56\xee\xf5\x0e\x6b\xbf\x68\xcc\xe5\xcf\x7f\x5d\x79\x56\x57\xdb\x15\x3c\xa5\xf3\xff\xbf\x36\x42\x74\x06\xf9\x52\x54\x3c\x4d\xc2\x5d\x9d\x4d\x41\x09\x91\x76\xf5\x98\x5c\x49\xba\xac\x6a\x95\xe7\x82\xee\xdb\xe5\xd8\x7a\xee\xd0\x92\xc3\xb3\xa5\xec\xda\xad\xa7\x5e\xeb\xb2\x6b\x7e\x66\x72\x38\xaa\x8c\x82\xba\x21\xb0\x51\x93\xb7\x24\xaf\xac\x15\xa6\x36\x68\xef\x54\x5a\xae\x25\xab\xdc\x51\xe8\x0b\x3f\x72\x68\x0e\x33\x83\x06\x36\x8a\xc2\xdb\xae\x3f\x95\xed\x74\xb8\x2e\x71\x90\xb4\x42\xe2\x88\xa3\xe9\x6a\xad\x7a\xc9\x17\x4b\xa7\x95\xe6\x7e\x64\x06\x49\xab\xe6\x47\xea\x48\x2d\xb9\x74\x37\x32\xb1\x1b\xa5\xe4\xf1\x7f\x5c\x55\x1b\x24\xf2\x29\x95\xb5\x89\x5e\x4c\xa1\xc9\xe9\x42\xe5\xc7\x6a\x79\x9f\x4e\x33\x42\xb7\x7e\xb4\xbe\x53\x31\x3e\x8f\xff\xdb\x77\x3a\x92\xd8\xa6\x87\x38\xba\x22\xfb\xa7\xbb\x88\xe3\x43\x98\xe6\xee\x60\xa6\x7b\xb9\x41\x99\xfc\x78\xbe\x50\x65\xda\x82\x66\x30\xfa\xdd\x68\xf4\x48\xbd\x14\x88\xe4\xdf\x7a\xe9\x49\x62\xab\x7f\xf4\x0e\x20\xb5\xb2\xe1\xc6\x37\x2e\xa7\x25\xad\x32\x9a\x0c\xd5\x2b\x26\xda\xf7\x3b\x8e\x8c\xdc\x97\x68\xe5\xee\x3a\xa0\xd1\xc6\xe3\x0e\x5d\xfe\xf5\x02\xee\x88\x6b\xa7\x51\x74\x0f\x38\xcf\xbe\xe2\x01\xe7\xd9\xc3\x0f\x38\xb1\xff\x0b\x77\xdf\xdd\x58\xd7\x34\x37\xf2\x11\xd2\x5d\xa8\xa3\x6f\x14\xc2\x1d\x95\xe6\xda\x76\xde\xb9\xaa\xb5\x76\xb7\x12\x84\x74\x14\x3a\xec\x47\xee\xae\x79\x6f\xa8\xb0\x79\xf6\xbd\xe1\xf2\x64\xb8\xae\x39\x88\x23\x66\x0c\xd7\xf6\x4c\x39\xdd\x72\xad\x57\x16\xf8\x2f\x01\xad\x42\xed\x21\x76\x3a\x99\xf5\x37\xdd\x29\xfc\xd3\x8c\x86\xd0\x36\x57\x3a\x07\x81\xca\xb5\xb9\x87\xbb\xfd\xd8\x99\x7c\xf4\xb8\x79\x14\x3d\x6e\x62\x04\x15\x61\xc4\x14\xa3\x74\x8f\x36\x32\xb9\x3e\xfa\x66\x5e\xd6\x52\xb7\xd6\x80\x6e\x98\x3a\xf4\xad\x82\xbe\x3b\xf5\xdf\x26\x38\x3c\x89\xbb\xd7\x47\x2f\xa0\x7f\x35\xdf\x75\x64\x48\xce\x52\xab\x6b\x6e\xf2\xde\x57\xbb\xb9\xe1\x36\xb5\xba\xe6\x0d\x61\x9d\x1b\x75\xbd\x88\xd2\x9e\x86\xbb\x6f\x7b\x70\xcb\x35\x4c\x53\x56\x99\x70\x69\x8d\x26\xe7\x88\x46\x86\xdb\x9e\xab\x16\xd3\x91\x01\xa2\x78\xa9\xd5\x02\xf5\xe2\x7a\xeb\x87\xea\x81\xd1\x27\x2b\xc8\x2c\x92\xd8\xb9\x15\x41\xd7\xb6\x22\xcd\x0b\x2e\x6e\x78\x79\xc9\xef\xac\xbf\x16\xd2\x3b\x6a\x6a\xfe\xd6\x62\x31\x59\xb2\x82\xa7\xc1\xa3\xeb\xe9\xdb\xd1\x58\xbe\x1b\x0c\x7c\x72\xe8\x61\xc2\xce\xb0\xb9\x78\xe0\x32\x40\x23\xad\x4a\xa6\xc9\x84\x3b\x05\xa0\x33\x06\xc7\x6b\x46\xe6\x24\xba\x76\xac\xd0\x11\x03\xc5\x85\x4b\x85\x52\xf0\x63\x88\xbe\x8b\xaf\x48\x92\xf0\x3c\xdc\x5e\x5d\x8e\x0e\x64\xe3\x13\x12\x99\x9b\x5d\xba\x4e\xb5\x87\xbd\x93\xe3\xc4\xb4\x91\xdc\x2b\x66\xce\x35\x9f\x8a\xbb\xb4\x2b\x91\xcc\x7f\xc8\x92\x38\xd3\x89\x96\xf4\x69\x74\x47\xe0\x93\x65\x25\xec\xd9\xea\x1a\x48\x32\x38\x18\x84\xf3\x0c\x84\x4f\x30\x61\x87\x4e\x96\xb0\xd0\x59\xe8\x81\x43\xeb\xc0\x0e\x81\x5e\xbc\xdd\x7f\x87\xcf\x3e\xf6\xa4\x3f\x4d\x93\x17\xc5\x5c\xd1\x4d\x99\x9b\x35\x1e\xe9\x2a\x8e\x9b\x81\xaf\x4b\xf2\x61\x1a\xc1\xd5\x5f\xa8\x08\x92\xd4\x23\xc5\xbf\x66\x7e\xcd\xa5\xc0\x15\xf3\x9b\xb6\xd6\x17\x40\xe0\x9a\x15\xef\x37\xcb\xe2\x73\xa5\xd0\x5b\xd7\x1c\x0c\x7c\x15\x03\x6d\xa8\x7e\xa4\x84\xdc\xe9\x55\x2b\xa5\x76\x00\xb2\x52\x1b\xbd\x97\xea\x56\xfa\x70\xe1\xbe\xb3\x0b\xcb\xdc\xdc\xea\x89\x19\xc3\x93\x9b\x75\xf1\x64\x3d\x25\x34\x47\x6b\xfe\x7b\x90\xc2\x7e\x9d\xbc\xbb\xe1\x0b\x85\x4f\x64\xde\x9d\xa7\xc1\x1b\x92\x6f\x37\x4b\x3e\x3e\xfb\xd2\xa7\x38\x9f\x4e\xbf\x21\x2b\xf6\xa9\x74\xd9\xb7\x37\xf5\xfd\xba\xf9\xb7\x47\xdd\xae\x04\x1c\x56\xed\x4e\xbf\x6e\xd6\xba\x39\xfd\x76\x3e\x8e\xfb\xd7\xe7\xdf\xee\x97\x78\x8f\x4d\xc0\x45\xb7\x06\x6a\xf8\x76\xdf\x7a\x92\x2a\x3e\x2b\xdd\x12\x45\x6b\xf9\xb6\xe7\x30\xfe\xd2\xbd\xec\xdc\x51\x6e\xbe\x61\xa3\x4d\x5b\xb2\x8a\x66\x10\xfd\xb8\xf4\xef\x25\xec\x1c\xd7\x91\xb4\x33\x5c\xfc\x17\xd7\x03\x44\xe1\xa7\x0a\x82\xa2\x3d\x67\xd8\x58\x05\x7c\x71\xda\x7f\x80\x9c\xfe\xe7\xe7\xfd\x3e\x93\x0f\x4b\xfc\xeb\x92\xa7\x6c\xff\x99\xe9\xfd\x51\x62\xfe\x2a\xf9\x7d\x03\xcf\x8f\xe2\x76\x9d\xc0\x2f\xca\xde\x8f\x12\xc0\x23\xd3\xb7\x0f\x3f\x5f\x9c\xbf\x29\x3a\xb6\x49\xa0\x1d\xef\xf7\x7c\xce\x9b\x33\x7d\xf9\xd6\xe6\xf3\x66\x68\xf5\xca\x3b\x57\xba\x39\x7f\x75\x84\x34\xe3\x16\xba\x37\x96\xfd\xb9\x57\x73\x27\xb3\xf9\x12\x6f\x15\x8b\x3b\x4a\xcd\xa0\xe4\x96\x89\x0a\x3a\x9f\x51\xae\xcf\x4a\x9a\x6f\x75\xd0\x29\xe8\xf3\x42\x55\x14\xb5\xd6\xbc\x1c\xa3\x70\x28\x2d\x3a\x3c\xed\x01\xce\xc7\xf8\x3f\x03\x00\x00\xff\xff\xeb\xa4\x00\xb2\x80\x4d\x00\x00") func testImagesAgnhostNetexecNetexecGoBytes() ([]byte, error) { return bindataRead( @@ -6225,7 +6225,7 @@ func testImagesSampleApiserverBaseimage() (*asset, error) { return a, nil } -var _testImagesSampleApiserverDockerfile = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x54\x5f\x4f\xe3\xc8\x13\x7c\xf7\xa7\x28\xc5\x3c\xfc\x7e\x12\xb6\x13\x74\xba\x45\xac\x90\xce\x84\x6c\xb0\x16\x62\x14\x87\x5d\xa1\xbb\x53\x34\xb1\x3b\xf6\x1c\xf6\x8c\x6f\xfe\x24\x44\xab\xfd\xee\xa7\x19\x03\x0b\xc7\x49\x9b\xa7\xb8\xa7\xa7\xab\xa6\xba\xab\x43\x4c\x65\x7f\x50\xbc\x6e\x0c\x4e\xc6\x93\x53\xac\x1a\xc2\x67\xbb\x21\x25\xc8\x90\x46\x6a\x4d\x23\x95\x8e\x83\x30\x08\x71\xcd\x4b\x12\x9a\x2a\x58\x51\x91\x82\x69\x08\x69\xcf\xca\x86\x9e\x4f\x8e\xf1\x85\x94\xe6\x52\xe0\x24\x1e\xe3\x7f\x2e\x61\xf4\x74\x34\xfa\xff\xc7\x20\xc4\x41\x5a\x74\xec\x00\x21\x0d\xac\x26\x98\x86\x6b\x6c\x79\x4b\xa0\xc7\x92\x7a\x03\x2e\x50\xca\xae\x6f\x39\x13\x25\x61\xcf\x4d\xe3\x61\x9e\x8a\xc4\x41\x88\xfb\xa7\x12\x72\x63\x18\x17\x60\x28\x65\x7f\x80\xdc\xbe\xce\x03\x33\x9e\xb0\xfb\x35\xc6\xf4\x67\x49\xb2\xdf\xef\x63\xe6\xc9\xc6\x52\xd5\x49\x3b\x24\xea\xe4\x3a\x9b\xce\x16\xc5\x2c\x3a\x89\xc7\xfe\xca\x9d\x68\x49\x6b\x28\xfa\xdb\x72\x45\x15\x36\x07\xb0\xbe\x6f\x79\xc9\x36\x2d\xa1\x65\x7b\x48\x05\x56\x2b\xa2\x0a\x46\x3a\xbe\x7b\xc5\x0d\x17\xf5\x31\xb4\xdc\x9a\x3d\x53\x14\x84\xa8\xb8\x36\x8a\x6f\xac\x79\x23\xd6\x33\x3b\xae\xdf\x24\x48\x01\x26\x30\x4a\x0b\x64\xc5\x08\x17\x69\x91\x15\xc7\x41\x88\xaf\xd9\xea\x2a\xbf\x5b\xe1\x6b\xba\x5c\xa6\x8b\x55\x36\x2b\x90\x2f\x31\xcd\x17\x97\xd9\x2a\xcb\x17\x05\xf2\x4f\x48\x17\xf7\xf8\x9c\x2d\x2e\x8f\x41\xdc\x34\xa4\x40\x8f\xbd\x72\xfc\xa5\x02\x77\x32\x52\xe5\x34\x2b\x88\xde\x10\xd8\xca\x81\x90\xee\xa9\xe4\x5b\x5e\xa2\x65\xa2\xb6\xac\x26\xd4\x72\x47\x4a\x70\x51\xa3\x27\xd5\x71\xed\x9a\xa9\xc1\x44\x15\x84\x68\x79\xc7\x0d\x33\x3e\xf2\xee\x51\x71\x10\xa4\xcb\xb9\x63\x3f\xcb\x6e\xd2\xf9\x2c\xf8\xb4\xcc\x6f\x60\x75\x5c\x97\x2a\xe6\x32\x79\x38\xd5\x11\x53\x86\x6f\x59\x69\x74\xd4\x2b\x59\x25\x1b\xcb\xdb\x2a\xe2\x1d\xab\x29\x79\xb0\x1b\x8a\x4a\x25\xb5\x3e\xdb\x4d\xe2\xc9\x2f\xf1\xaf\xd1\x04\x4c\xc3\xe7\xac\x1f\x4e\xf5\x7a\xb2\x9e\x7c\x58\x6b\xd6\xf5\x2d\xad\x59\xcf\x35\xa9\x1d\xa9\x20\x98\x2d\xbe\x60\x9e\xdf\xa6\xab\x2b\x24\xb5\x0c\x96\x77\x0b\x74\x0f\x15\x57\x88\x7a\x1c\x7d\x1b\x4e\xbe\x27\x5a\x95\xaf\xbe\x36\x5c\xf8\x7b\xfe\xd6\xd1\x10\x75\xc1\xb3\x23\xf7\x2f\x08\x82\xd0\xdb\x80\x4e\x08\xac\xae\x15\xd5\xcc\x38\xc1\x48\x1b\xdf\x3a\xd2\xbc\x16\x43\xfb\x7d\x8c\x6d\x78\xcb\xcd\xc1\x7d\x2b\x2b\x30\x70\x8c\x5e\x38\xba\x67\x30\xf1\x52\x89\x2a\x0c\x71\xd7\x18\x4d\x03\x8c\xaf\x23\x58\x47\x15\x46\x45\x23\x6d\x5b\x61\x43\xf0\x23\x67\x24\xb4\xed\x7b\xa9\x8c\x97\x7b\x12\x4f\x3e\xa0\xf0\x10\x48\x6f\x33\x14\x03\x86\xd5\xae\x67\x2e\xa1\xb4\x4a\x91\x30\x48\x5f\x98\x8f\xdc\x83\x2e\x9c\x90\x70\xda\x7e\x88\xc7\xae\x28\x09\x6d\x15\xbd\xb9\xa2\xa8\x25\xa6\xe9\x19\x4f\x83\xa1\x57\x5c\x2a\xec\x9e\x5c\xfd\xe4\xb2\xe1\x85\xf8\xd1\x85\x10\x73\x32\xde\xad\xd2\x9a\xa1\x67\x9e\x8e\x44\x2f\x7b\xdb\x32\x43\xe8\x64\x65\x5b\x42\xe9\x1c\xe8\xbb\x34\xcf\x27\x93\xc9\x4d\x7e\x79\x77\x3d\x3b\x97\x02\xb5\x44\x4d\x06\x51\x85\x87\x53\xed\x06\xe6\xdf\x32\xfe\xb6\x1b\x7b\xee\xaf\xc0\x90\x17\x49\xba\x9c\x5e\x45\x2f\x73\x4c\x62\xe7\x50\x3d\x83\xff\x42\x99\xce\xf3\xf5\x6c\x91\x5e\x5c\xcf\x2e\xcf\xc7\x98\xe7\x79\x71\xde\x72\x61\x1f\x31\xcf\x5d\xa1\x73\x37\xbe\xee\xcf\x33\x9d\x9f\x71\x09\x42\xef\x25\xa6\xba\x63\x77\x85\x0b\x6d\x58\xdb\xba\xd5\xa6\x51\x4b\x37\x53\x89\xaf\xbf\xf6\x19\x5a\xe2\x2f\xab\x0d\xb6\x5c\x54\x5e\x48\xbf\xf9\x98\xa8\x86\x1d\xc6\x8d\x1f\xa9\x86\xa0\xa4\x34\xd0\x32\x08\xb1\x77\x92\x89\x97\x73\x27\xef\x56\xc9\x6e\x58\x9c\xa6\x51\x72\x0f\xb6\x67\x07\x94\x52\xb8\x75\x48\xce\xf6\xce\xc7\x3e\x89\x41\x1b\x26\x2a\xa6\x2a\xb4\xb2\xf4\xce\xf5\xa2\x78\xfc\x64\xe0\x87\xc8\x8d\xdd\xfb\xa1\x8d\xe8\x91\x4a\x94\x3d\xbe\x7d\x47\x82\x3f\x3e\x06\x83\xa1\x8f\x7e\x18\x7c\x9a\xdf\xde\x23\x8a\x1c\xd2\xf9\x4f\x6c\x8a\x77\x0a\xbe\x8f\x38\x2b\xaf\x96\xf7\xb7\x79\xb6\x58\xe1\xf7\xd1\xbb\xf3\xd1\x9f\xc1\x3f\x01\x00\x00\xff\xff\x3d\x13\x08\x96\xad\x06\x00\x00") +var _testImagesSampleApiserverDockerfile = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x54\xef\x4f\xe3\x46\x10\xfd\xee\xbf\xe2\x29\xe6\x43\x2b\x61\x3b\x41\xaa\x0e\x71\x42\xaa\x09\xb9\x60\x1d\xc4\x28\x0e\x77\x42\x6d\x15\x6d\xec\x89\xbd\xc5\xde\x75\xf7\x47\x42\x74\xba\xff\xbd\xda\x35\x70\x50\x2a\x5d\x3e\xc5\xb3\xb3\xf3\xde\xbe\x99\x37\x21\xa6\xb2\x3f\x28\x5e\x37\x06\x27\xe3\xc9\x29\x56\x0d\xe1\xb3\xdd\x90\x12\x64\x48\x23\xb5\xa6\x91\x4a\xc7\x41\x18\x84\xb8\xe6\x25\x09\x4d\x15\xac\xa8\x48\xc1\x34\x84\xb4\x67\x65\x43\xcf\x27\xc7\xf8\x42\x4a\x73\x29\x70\x12\x8f\xf1\x8b\x4b\x18\x3d\x1d\x8d\x7e\xfd\x18\x84\x38\x48\x8b\x8e\x1d\x20\xa4\x81\xd5\x04\xd3\x70\x8d\x2d\x6f\x09\xf4\x58\x52\x6f\xc0\x05\x4a\xd9\xf5\x2d\x67\xa2\x24\xec\xb9\x69\x3c\xcc\x53\x91\x38\x08\x71\xff\x54\x42\x6e\x0c\xe3\x02\x0c\xa5\xec\x0f\x90\xdb\xd7\x79\x60\xc6\x13\x76\xbf\xc6\x98\xfe\x2c\x49\xf6\xfb\x7d\xcc\x3c\xd9\x58\xaa\x3a\x69\x87\x44\x9d\x5c\x67\xd3\xd9\xa2\x98\x45\x27\xf1\xd8\x5f\xb9\x13\x2d\x69\x0d\x45\xff\x58\xae\xa8\xc2\xe6\x00\xd6\xf7\x2d\x2f\xd9\xa6\x25\xb4\x6c\x0f\xa9\xc0\x6a\x45\x54\xc1\x48\xc7\x77\xaf\xb8\xe1\xa2\x3e\x86\x96\x5b\xb3\x67\x8a\x82\x10\x15\xd7\x46\xf1\x8d\x35\x6f\xc4\x7a\x66\xc7\xf5\x9b\x04\x29\xc0\x04\x46\x69\x81\xac\x18\xe1\x22\x2d\xb2\xe2\x38\x08\xf1\x35\x5b\x5d\xe5\x77\x2b\x7c\x4d\x97\xcb\x74\xb1\xca\x66\x05\xf2\x25\xa6\xf9\xe2\x32\x5b\x65\xf9\xa2\x40\xfe\x09\xe9\xe2\x1e\x9f\xb3\xc5\xe5\x31\x88\x9b\x86\x14\xe8\xb1\x57\x8e\xbf\x54\xe0\x4e\x46\xaa\x9c\x66\x05\xd1\x1b\x02\x5b\x39\x10\xd2\x3d\x95\x7c\xcb\x4b\xb4\x4c\xd4\x96\xd5\x84\x5a\xee\x48\x09\x2e\x6a\xf4\xa4\x3a\xae\x5d\x33\x35\x98\xa8\x82\x10\x2d\xef\xb8\x61\xc6\x47\xde\x3d\x2a\x0e\x82\x74\x39\x77\xec\x67\xd9\x4d\x3a\x9f\x05\x9f\x96\xf9\x0d\x1e\x4e\x75\x5c\x97\x2a\xe6\x32\xd9\x58\xde\x56\x11\xef\x58\x4d\xc9\x83\xdd\x50\x54\x2a\xa9\xf5\xd9\x6e\x12\x4f\x7e\x8b\xc7\xd1\x04\x4c\xc3\xe7\xac\x1f\x4e\xf5\x7a\xb2\x9e\x7c\x58\x6b\xd6\xf5\x2d\xad\x59\xcf\x35\xa9\x1d\xa9\x20\x98\x2d\xbe\x60\x9e\xdf\xa6\xab\x2b\x24\xb5\x0c\x96\x77\x0b\x74\x0f\x15\x57\x88\x7a\x1c\x7d\x1b\x4e\xbe\x27\x5a\x95\xaf\xbe\x36\x5c\xf8\x7b\xfe\xd6\xd1\x10\x75\xc1\xb3\x23\xf7\x2f\x08\x82\xd0\x0f\x3d\x9d\x10\x58\x5d\x2b\xaa\x99\x71\xf2\x90\x36\xbe\x51\xa4\x79\x2d\x86\x66\xfb\x18\xdb\xf0\x96\x9b\x83\xfb\x56\x56\x60\xe0\x18\xbd\x70\x74\xcf\x60\xe2\xa5\x12\x55\x18\xe2\xae\x0d\x9a\x06\x18\x5f\x47\xb0\x8e\x2a\x8c\x8a\x46\xda\xb6\xc2\x86\xe0\x07\xcc\x48\x68\xdb\xf7\x52\x19\x2f\xee\x24\x9e\x7c\x40\xe1\x21\x90\xde\x66\x28\x06\x0c\xab\x5d\x87\x5c\x42\x69\x95\x22\x61\x90\xbe\x30\x1f\xb9\x07\x5d\x38\x21\xe1\xb4\xfd\x10\x8f\x5d\x51\x12\xda\x2a\x7a\x73\x45\x51\x4b\x4c\xd3\x33\x9e\x06\x43\xaf\xb8\x54\xd8\x3d\x79\xf8\xc9\x53\xc3\x0b\xf1\xa3\x0b\x21\xe6\x64\xbc\x37\xa5\x35\x43\xcf\x3c\x1d\x89\x5e\xf6\xb6\x65\x86\xd0\xc9\xca\xb6\x84\xd2\xf9\xcd\x77\x69\x9e\x4f\x26\x93\x9b\xfc\xf2\xee\x7a\x76\x2e\x05\x6a\x89\x9a\x0c\xa2\xca\x4f\x08\x97\xc9\x7f\x65\xfc\x7d\x37\xf6\xdc\x5f\x81\x21\x2f\x92\x74\x39\xbd\x8a\x5e\xa6\x96\xc4\xce\xa1\x7a\x06\xff\x87\x32\x9d\xe7\xeb\xd9\x22\xbd\xb8\x9e\x5d\x9e\x8f\x31\xcf\xf3\xe2\xbc\xe5\xc2\x3e\x62\x9e\xbb\x42\xe7\x6e\x58\xdd\x9f\x67\x3a\x3f\xe3\x12\x84\xde\x39\x4c\x75\xc7\xee\x0a\x17\xda\xb0\xb6\x75\x8b\x4c\xa3\x96\x6e\xa6\x12\x5f\x7f\xed\x33\xb4\xc4\xdf\x56\x1b\x6c\xb9\xa8\xbc\x90\x7e\xcf\x31\x51\x0d\x1b\x8b\x1b\x3f\x52\x0d\x41\x49\x69\xa0\x65\x10\x62\xef\x24\x13\x2f\xe7\x4e\xde\xad\x92\xdd\xb0\x26\x4d\xa3\xe4\x1e\x6c\xcf\x0e\x28\xa5\x70\xcb\x8f\x9c\xc9\x9d\x6b\x7d\x12\x83\x36\x4c\x54\x4c\x55\x68\x65\xe9\x7d\xea\x45\xf1\xf8\xc9\xc0\x0f\x91\x1b\xbb\xf7\x43\x1b\xd1\x23\x95\x28\x7b\x7c\xfb\x8e\x04\x7f\x7e\x0c\x06\xfb\x1e\xfd\xb0\xf3\x34\xbf\xbd\x47\x14\x39\xa4\xf3\x9f\xd8\x14\xef\x14\x7c\x1f\x71\x56\x5e\x2d\xef\x6f\xf3\x6c\xb1\xc2\x1f\xa3\x77\xe7\xa3\xbf\x82\x7f\x03\x00\x00\xff\xff\x2b\x22\x73\x84\x9b\x06\x00\x00") func testImagesSampleApiserverDockerfileBytes() ([]byte, error) { return bindataRead( diff --git a/vendor/k8s.io/kubernetes/test/e2e/instrumentation/events.go b/vendor/k8s.io/kubernetes/test/e2e/instrumentation/events.go index 98db0f9164c1..74e28befb213 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/instrumentation/events.go +++ b/vendor/k8s.io/kubernetes/test/e2e/instrumentation/events.go @@ -85,10 +85,11 @@ var _ = common.SIGDescribe("Events API", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: New Event resource lifecycle, testing a single event Description: Create an event, the event MUST exist. The event is patched with a new note, the check MUST have the update note. + The event is updated with a new series, the check MUST have the update series. The event is deleted and MUST NOT show up when listing all events. */ framework.ConformanceIt("should ensure that an event can be fetched, patched, deleted, and listed", func() { @@ -147,6 +148,24 @@ var _ = common.SIGDescribe("Events API", func() { framework.Failf("test event wasn't properly patched: %v", diff.ObjectReflectDiff(testEvent, event)) } + ginkgo.By("updating the test event") + testEvent.Series = &eventsv1.EventSeries{ + Count: 100, + LastObservedTime: metav1.MicroTime{Time: time.Unix(1505828956, 0)}, + } + _, err = client.Update(context.TODO(), testEvent, metav1.UpdateOptions{}) + framework.ExpectNoError(err, "failed to update the test event") + + ginkgo.By("getting the test event") + event, err = client.Get(context.TODO(), eventName, metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get test event") + // clear ResourceVersion and ManagedFields which are set by control-plane + event.ObjectMeta.ResourceVersion = "" + event.ObjectMeta.ManagedFields = nil + if !apiequality.Semantic.DeepEqual(testEvent, event) { + framework.Failf("test event wasn't properly updated: %v", diff.ObjectReflectDiff(testEvent, event)) + } + ginkgo.By("deleting the test event") err = client.Delete(context.TODO(), eventName, metav1.DeleteOptions{}) framework.ExpectNoError(err, "failed to delete the test event") @@ -161,7 +180,7 @@ var _ = common.SIGDescribe("Events API", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: New Event resource lifecycle, testing a list of events Description: Create a list of events, the events MUST exist. The events are deleted and MUST NOT show up when listing all events. diff --git a/vendor/k8s.io/kubernetes/test/e2e/kubectl/BUILD b/vendor/k8s.io/kubernetes/test/e2e/kubectl/BUILD index 22170f4ef67d..362d887da74f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/kubectl/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/kubectl/BUILD @@ -39,6 +39,7 @@ go_library( "//test/e2e/framework/node:go_default_library", "//test/e2e/framework/pod:go_default_library", "//test/e2e/framework/service:go_default_library", + "//test/e2e/framework/skipper:go_default_library", "//test/e2e/framework/testfiles:go_default_library", "//test/e2e/framework/websocket:go_default_library", "//test/e2e/scheduling:go_default_library", diff --git a/vendor/k8s.io/kubernetes/test/e2e/kubectl/kubectl.go b/vendor/k8s.io/kubernetes/test/e2e/kubectl/kubectl.go index 3004d4327713..1127900a47be 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/kubectl/kubectl.go +++ b/vendor/k8s.io/kubernetes/test/e2e/kubectl/kubectl.go @@ -69,6 +69,7 @@ import ( e2enode "k8s.io/kubernetes/test/e2e/framework/node" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2eservice "k8s.io/kubernetes/test/e2e/framework/service" + e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" e2etestfiles "k8s.io/kubernetes/test/e2e/framework/testfiles" "k8s.io/kubernetes/test/e2e/scheduling" testutils "k8s.io/kubernetes/test/utils" @@ -313,7 +314,7 @@ var _ = SIGDescribe("Kubectl client", func() { nautilus = commonutils.SubstituteImageName(string(data)) }) /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, replication controller Description: Create a Pod and a container with a given image. Configure replication controller to run 2 replicas. The number of running instances of the Pod MUST equal the number of replicas set on the replication controller which is 2. */ @@ -321,12 +322,12 @@ var _ = SIGDescribe("Kubectl client", func() { defer cleanupKubectlInputs(nautilus, ns, updateDemoSelector) ginkgo.By("creating a replication controller") - framework.RunKubectlOrDieInput(ns, nautilus, "create", "-f", "-", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDieInput(ns, nautilus, "create", "-f", "-") validateController(c, nautilusImage, 2, "update-demo", updateDemoSelector, getUDData("nautilus.jpg", ns), ns) }) /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, scale replication controller Description: Create a Pod and a container with a given image. Configure replication controller to run 2 replicas. The number of running instances of the Pod MUST equal the number of replicas set on the replication controller which is 2. Update the replicaset to 1. Number of running instances of the Pod MUST be 1. Update the replicaset to 2. Number of running instances of the Pod MUST be 2. */ @@ -334,15 +335,15 @@ var _ = SIGDescribe("Kubectl client", func() { defer cleanupKubectlInputs(nautilus, ns, updateDemoSelector) ginkgo.By("creating a replication controller") - framework.RunKubectlOrDieInput(ns, nautilus, "create", "-f", "-", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDieInput(ns, nautilus, "create", "-f", "-") validateController(c, nautilusImage, 2, "update-demo", updateDemoSelector, getUDData("nautilus.jpg", ns), ns) ginkgo.By("scaling down the replication controller") debugDiscovery() - framework.RunKubectlOrDie(ns, "scale", "rc", "update-demo-nautilus", "--replicas=1", "--timeout=5m", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDie(ns, "scale", "rc", "update-demo-nautilus", "--replicas=1", "--timeout=5m") validateController(c, nautilusImage, 1, "update-demo", updateDemoSelector, getUDData("nautilus.jpg", ns), ns) ginkgo.By("scaling up the replication controller") debugDiscovery() - framework.RunKubectlOrDie(ns, "scale", "rc", "update-demo-nautilus", "--replicas=2", "--timeout=5m", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDie(ns, "scale", "rc", "update-demo-nautilus", "--replicas=2", "--timeout=5m") validateController(c, nautilusImage, 2, "update-demo", updateDemoSelector, getUDData("nautilus.jpg", ns), ns) }) }) @@ -368,7 +369,7 @@ var _ = SIGDescribe("Kubectl client", func() { } /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, guestbook application Description: Create Guestbook application that contains an agnhost primary server, 2 agnhost replicas, frontend application, frontend service and agnhost primary service and agnhost replica service. Using frontend service, the test will write an entry into the guestbook application which will store the entry into the backend agnhost store. Application flow MUST work as expected and the data written MUST be available to read. */ @@ -379,7 +380,7 @@ var _ = SIGDescribe("Kubectl client", func() { ginkgo.By("creating all guestbook components") forEachGBFile(func(contents string) { framework.Logf(contents) - framework.RunKubectlOrDieInput(ns, contents, "create", "-f", "-", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDieInput(ns, contents, "create", "-f", "-") }) ginkgo.By("validating guestbook app") @@ -392,7 +393,7 @@ var _ = SIGDescribe("Kubectl client", func() { ginkgo.BeforeEach(func() { ginkgo.By(fmt.Sprintf("creating the pod from %v", podYaml)) podYaml = commonutils.SubstituteImageName(string(readTestFileOrDie("pod-with-readiness-probe.yaml.in"))) - framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-", fmt.Sprintf("--namespace=%v", ns)) + framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-") framework.ExpectEqual(e2epod.CheckPodsRunningReady(c, ns, []string{simplePodName}, framework.PodStartTimeout), true) }) ginkgo.AfterEach(func() { @@ -401,7 +402,7 @@ var _ = SIGDescribe("Kubectl client", func() { ginkgo.It("should support exec", func() { ginkgo.By("executing a command in the container") - execOutput := framework.RunKubectlOrDie(ns, "exec", fmt.Sprintf("--namespace=%v", ns), simplePodName, "echo", "running", "in", "container") + execOutput := framework.RunKubectlOrDie(ns, "exec", simplePodName, "echo", "running", "in", "container") if e, a := "running in container", strings.TrimSpace(execOutput); e != a { framework.Failf("Unexpected kubectl exec output. Wanted %q, got %q", e, a) } @@ -411,11 +412,11 @@ var _ = SIGDescribe("Kubectl client", func() { for i := 0; i < len(veryLongData); i++ { veryLongData[i] = 'a' } - execOutput = framework.RunKubectlOrDie(ns, "exec", fmt.Sprintf("--namespace=%v", ns), simplePodName, "echo", string(veryLongData)) + execOutput = framework.RunKubectlOrDie(ns, "exec", simplePodName, "echo", string(veryLongData)) framework.ExpectEqual(string(veryLongData), strings.TrimSpace(execOutput), "Unexpected kubectl exec output") ginkgo.By("executing a command in the container with noninteractive stdin") - execOutput = framework.NewKubectlCommand(ns, "exec", fmt.Sprintf("--namespace=%v", ns), "-i", simplePodName, "cat"). + execOutput = framework.NewKubectlCommand(ns, "exec", "-i", simplePodName, "cat"). WithStdinData("abcd1234"). ExecOrDie(ns) if e, a := "abcd1234", execOutput; e != a { @@ -431,7 +432,7 @@ var _ = SIGDescribe("Kubectl client", func() { defer closer.Close() ginkgo.By("executing a command in the container with pseudo-interactive stdin") - execOutput = framework.NewKubectlCommand(ns, "exec", fmt.Sprintf("--namespace=%v", ns), "-i", simplePodName, "sh"). + execOutput = framework.NewKubectlCommand(ns, "exec", "-i", simplePodName, "sh"). WithStdinReader(r). ExecOrDie(ns) if e, a := "hi", strings.TrimSpace(execOutput); e != a { @@ -441,7 +442,7 @@ var _ = SIGDescribe("Kubectl client", func() { ginkgo.It("should support exec using resource/name", func() { ginkgo.By("executing a command in the container") - execOutput := framework.RunKubectlOrDie(ns, "exec", fmt.Sprintf("--namespace=%v", ns), simplePodResourceName, "echo", "running", "in", "container") + execOutput := framework.RunKubectlOrDie(ns, "exec", simplePodResourceName, "echo", "running", "in", "container") if e, a := "running in container", strings.TrimSpace(execOutput); e != a { framework.Failf("Unexpected kubectl exec output. Wanted %q, got %q", e, a) } @@ -508,30 +509,28 @@ var _ = SIGDescribe("Kubectl client", func() { }) ginkgo.It("should return command exit codes", func() { - nsFlag := fmt.Sprintf("--namespace=%v", ns) - ginkgo.By("execing into a container with a successful command") - _, err := framework.NewKubectlCommand(ns, nsFlag, "exec", "httpd", "--", "/bin/sh", "-c", "exit 0").Exec() + _, err := framework.NewKubectlCommand(ns, "exec", "httpd", "--", "/bin/sh", "-c", "exit 0").Exec() framework.ExpectNoError(err) ginkgo.By("execing into a container with a failing command") - _, err = framework.NewKubectlCommand(ns, nsFlag, "exec", "httpd", "--", "/bin/sh", "-c", "exit 42").Exec() + _, err = framework.NewKubectlCommand(ns, "exec", "httpd", "--", "/bin/sh", "-c", "exit 42").Exec() ee, ok := err.(uexec.ExitError) framework.ExpectEqual(ok, true) framework.ExpectEqual(ee.ExitStatus(), 42) ginkgo.By("running a successful command") - _, err = framework.NewKubectlCommand(ns, nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "success", "--", "/bin/sh", "-c", "exit 0").Exec() + _, err = framework.NewKubectlCommand(ns, "run", "-i", "--image="+busyboxImage, "--restart=Never", "success", "--", "/bin/sh", "-c", "exit 0").Exec() framework.ExpectNoError(err) ginkgo.By("running a failing command") - _, err = framework.NewKubectlCommand(ns, nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "failure-1", "--", "/bin/sh", "-c", "exit 42").Exec() + _, err = framework.NewKubectlCommand(ns, "run", "-i", "--image="+busyboxImage, "--restart=Never", "failure-1", "--", "/bin/sh", "-c", "exit 42").Exec() ee, ok = err.(uexec.ExitError) framework.ExpectEqual(ok, true) framework.ExpectEqual(ee.ExitStatus(), 42) ginkgo.By("running a failing command without --restart=Never") - _, err = framework.NewKubectlCommand(ns, nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=OnFailure", "failure-2", "--", "/bin/sh", "-c", "cat && exit 42"). + _, err = framework.NewKubectlCommand(ns, "run", "-i", "--image="+busyboxImage, "--restart=OnFailure", "failure-2", "--", "/bin/sh", "-c", "cat && exit 42"). WithStdinData("abcd1234"). Exec() ee, ok = err.(uexec.ExitError) @@ -541,7 +540,7 @@ var _ = SIGDescribe("Kubectl client", func() { } ginkgo.By("running a failing command without --restart=Never, but with --rm") - _, err = framework.NewKubectlCommand(ns, nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=OnFailure", "--rm", "failure-3", "--", "/bin/sh", "-c", "cat && exit 42"). + _, err = framework.NewKubectlCommand(ns, "run", "-i", "--image="+busyboxImage, "--restart=OnFailure", "--rm", "failure-3", "--", "/bin/sh", "-c", "cat && exit 42"). WithStdinData("abcd1234"). Exec() ee, ok = err.(uexec.ExitError) @@ -552,18 +551,16 @@ var _ = SIGDescribe("Kubectl client", func() { e2epod.WaitForPodToDisappear(f.ClientSet, ns, "failure-3", labels.Everything(), 2*time.Second, wait.ForeverTestTimeout) ginkgo.By("running a failing command with --leave-stdin-open") - _, err = framework.NewKubectlCommand(ns, nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "failure-4", "--leave-stdin-open", "--", "/bin/sh", "-c", "exit 42"). + _, err = framework.NewKubectlCommand(ns, "run", "-i", "--image="+busyboxImage, "--restart=Never", "failure-4", "--leave-stdin-open", "--", "/bin/sh", "-c", "exit 42"). WithStdinData("abcd1234"). Exec() framework.ExpectNoError(err) }) ginkgo.It("should support inline execution and attach", func() { - nsFlag := fmt.Sprintf("--namespace=%v", ns) - ginkgo.By("executing a command with run and attach with stdin") // We wait for a non-empty line so we know kubectl has attached - runOutput := framework.NewKubectlCommand(ns, nsFlag, "run", "run-test", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--stdin", "--", "sh", "-c", "while [ -z \"$s\" ]; do read s; sleep 1; done; echo read:$s && cat && echo 'stdin closed'"). + runOutput := framework.NewKubectlCommand(ns, "run", "run-test", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--stdin", "--", "sh", "-c", "while [ -z \"$s\" ]; do read s; sleep 1; done; echo read:$s && cat && echo 'stdin closed'"). WithStdinData("value\nabcd1234"). ExecOrDie(ns) gomega.Expect(runOutput).To(gomega.ContainSubstring("read:value")) @@ -578,7 +575,7 @@ var _ = SIGDescribe("Kubectl client", func() { // "stdin closed", but hasn't exited yet. // We wait 10 seconds before printing to give time to kubectl to attach // to the container, this does not solve the race though. - runOutput = framework.NewKubectlCommand(ns, fmt.Sprintf("--namespace=%v", ns), "run", "run-test-2", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--", "sh", "-c", "sleep 10; cat && echo 'stdin closed'"). + runOutput = framework.NewKubectlCommand(ns, "run", "run-test-2", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--", "sh", "-c", "sleep 10; cat && echo 'stdin closed'"). WithStdinData("abcd1234"). ExecOrDie(ns) gomega.Expect(runOutput).ToNot(gomega.ContainSubstring("abcd1234")) @@ -587,7 +584,7 @@ var _ = SIGDescribe("Kubectl client", func() { gomega.Expect(c.CoreV1().Pods(ns).Delete(context.TODO(), "run-test-2", metav1.DeleteOptions{})).To(gomega.BeNil()) ginkgo.By("executing a command with run and attach with stdin with open stdin should remain running") - runOutput = framework.NewKubectlCommand(ns, nsFlag, "run", "run-test-3", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput = framework.NewKubectlCommand(ns, "run", "run-test-3", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234\n"). ExecOrDie(ns) gomega.Expect(runOutput).ToNot(gomega.ContainSubstring("stdin closed")) @@ -604,7 +601,7 @@ var _ = SIGDescribe("Kubectl client", func() { if !e2epod.CheckPodsRunningReady(c, ns, []string{runTestPod.Name}, 1*time.Second) { framework.Failf("Pod %q of Job %q should still be running", runTestPod.Name, "run-test-3") } - logOutput := framework.RunKubectlOrDie(ns, nsFlag, "logs", runTestPod.Name) + logOutput := framework.RunKubectlOrDie(ns, "logs", runTestPod.Name) gomega.Expect(logOutput).ToNot(gomega.ContainSubstring("stdin closed")) return strings.Contains(logOutput, "abcd1234"), nil }) @@ -614,17 +611,16 @@ var _ = SIGDescribe("Kubectl client", func() { }) ginkgo.It("should contain last line of the log", func() { - nsFlag := fmt.Sprintf("--namespace=%v", ns) podName := "run-log-test" ginkgo.By("executing a command with run") - framework.RunKubectlOrDie(ns, "run", podName, "--image="+busyboxImage, "--restart=OnFailure", nsFlag, "--", "sh", "-c", "sleep 10; seq 100 | while read i; do echo $i; sleep 0.01; done; echo EOF") + framework.RunKubectlOrDie(ns, "run", podName, "--image="+busyboxImage, "--restart=OnFailure", "--", "sh", "-c", "sleep 10; seq 100 | while read i; do echo $i; sleep 0.01; done; echo EOF") if !e2epod.CheckPodsRunningReadyOrSucceeded(c, ns, []string{podName}, framework.PodStartTimeout) { framework.Failf("Pod for run-log-test was not ready") } - logOutput := framework.RunKubectlOrDie(ns, nsFlag, "logs", "-f", "run-log-test") + logOutput := framework.RunKubectlOrDie(ns, "logs", "-f", "run-log-test") gomega.Expect(logOutput).To(gomega.ContainSubstring("EOF")) }) @@ -646,6 +642,10 @@ var _ = SIGDescribe("Kubectl client", func() { }) ginkgo.It("should handle in-cluster config", func() { + // TODO: Find a way to download and copy the appropriate kubectl binary, or maybe a multi-arch kubectl image + // for now this only works on amd64 + e2eskipper.SkipUnlessNodeOSArchIs("amd64") + ginkgo.By("adding rbac permissions") // grant the view permission widely to allow inspection of the `invalid` namespace and the default namespace err := e2eauth.BindClusterRole(f.ClientSet.RbacV1(), "view", f.Namespace.Name, @@ -772,7 +772,7 @@ metadata: ginkgo.Describe("Kubectl api-versions", func() { /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, check version v1 Description: Run kubectl to get api versions, output MUST contain returned versions with 'v1' listed. */ @@ -802,12 +802,11 @@ metadata: ginkgo.It("should apply a new configuration to an existing RC", func() { controllerJSON := commonutils.SubstituteImageName(string(readTestFileOrDie(agnhostControllerFilename))) - nsFlag := fmt.Sprintf("--namespace=%v", ns) ginkgo.By("creating Agnhost RC") - framework.RunKubectlOrDieInput(ns, controllerJSON, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, controllerJSON, "create", "-f", "-") ginkgo.By("applying a modified configuration") stdin := modifyReplicationControllerConfiguration(controllerJSON) - framework.NewKubectlCommand(ns, "apply", "-f", "-", nsFlag). + framework.NewKubectlCommand(ns, "apply", "-f", "-"). WithStdinReader(stdin). ExecOrDie(ns) ginkgo.By("checking the result") @@ -815,19 +814,18 @@ metadata: }) ginkgo.It("should reuse port when apply to an existing SVC", func() { serviceJSON := readTestFileOrDie(agnhostServiceFilename) - nsFlag := fmt.Sprintf("--namespace=%v", ns) ginkgo.By("creating Agnhost SVC") - framework.RunKubectlOrDieInput(ns, string(serviceJSON[:]), "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, string(serviceJSON[:]), "create", "-f", "-") ginkgo.By("getting the original port") - originalNodePort := framework.RunKubectlOrDie(ns, "get", "service", "agnhost-primary", nsFlag, "-o", "jsonpath={.spec.ports[0].port}") + originalNodePort := framework.RunKubectlOrDie(ns, "get", "service", "agnhost-primary", "-o", "jsonpath={.spec.ports[0].port}") ginkgo.By("applying the same configuration") - framework.RunKubectlOrDieInput(ns, string(serviceJSON[:]), "apply", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, string(serviceJSON[:]), "apply", "-f", "-") ginkgo.By("getting the port after applying configuration") - currentNodePort := framework.RunKubectlOrDie(ns, "get", "service", "agnhost-primary", nsFlag, "-o", "jsonpath={.spec.ports[0].port}") + currentNodePort := framework.RunKubectlOrDie(ns, "get", "service", "agnhost-primary", "-o", "jsonpath={.spec.ports[0].port}") ginkgo.By("checking the result") if originalNodePort != currentNodePort { @@ -839,23 +837,22 @@ metadata: deployment1Yaml := commonutils.SubstituteImageName(string(readTestFileOrDie(httpdDeployment1Filename))) deployment2Yaml := commonutils.SubstituteImageName(string(readTestFileOrDie(httpdDeployment2Filename))) deployment3Yaml := commonutils.SubstituteImageName(string(readTestFileOrDie(httpdDeployment3Filename))) - nsFlag := fmt.Sprintf("--namespace=%v", ns) ginkgo.By("deployment replicas number is 2") - framework.RunKubectlOrDieInput(ns, deployment1Yaml, "apply", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, deployment1Yaml, "apply", "-f", "-") ginkgo.By("check the last-applied matches expectations annotations") - output := framework.RunKubectlOrDieInput(ns, deployment1Yaml, "apply", "view-last-applied", "-f", "-", nsFlag, "-o", "json") + output := framework.RunKubectlOrDieInput(ns, deployment1Yaml, "apply", "view-last-applied", "-f", "-", "-o", "json") requiredString := "\"replicas\": 2" if !strings.Contains(output, requiredString) { framework.Failf("Missing %s in kubectl view-last-applied", requiredString) } ginkgo.By("apply file doesn't have replicas") - framework.RunKubectlOrDieInput(ns, deployment2Yaml, "apply", "set-last-applied", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, deployment2Yaml, "apply", "set-last-applied", "-f", "-") ginkgo.By("check last-applied has been updated, annotations doesn't have replicas") - output = framework.RunKubectlOrDieInput(ns, deployment1Yaml, "apply", "view-last-applied", "-f", "-", nsFlag, "-o", "json") + output = framework.RunKubectlOrDieInput(ns, deployment1Yaml, "apply", "view-last-applied", "-f", "-", "-o", "json") requiredString = "\"replicas\": 2" if strings.Contains(output, requiredString) { framework.Failf("Presenting %s in kubectl view-last-applied", requiredString) @@ -864,13 +861,13 @@ metadata: ginkgo.By("scale set replicas to 3") httpdDeploy := "httpd-deployment" debugDiscovery() - framework.RunKubectlOrDie(ns, "scale", "deployment", httpdDeploy, "--replicas=3", nsFlag) + framework.RunKubectlOrDie(ns, "scale", "deployment", httpdDeploy, "--replicas=3") ginkgo.By("apply file doesn't have replicas but image changed") - framework.RunKubectlOrDieInput(ns, deployment3Yaml, "apply", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, deployment3Yaml, "apply", "-f", "-") ginkgo.By("verify replicas still is 3 and image has been updated") - output = framework.RunKubectlOrDieInput(ns, deployment3Yaml, "get", "-f", "-", nsFlag, "-o", "json") + output = framework.RunKubectlOrDieInput(ns, deployment3Yaml, "get", "-f", "-", "-o", "json") requiredItems := []string{"\"replicas\": 3", imageutils.GetE2EImage(imageutils.Httpd)} for _, item := range requiredItems { if !strings.Contains(output, item) { @@ -882,13 +879,11 @@ metadata: ginkgo.Describe("Kubectl diff", func() { /* - Release : v1.19 + Release: v1.19 Testname: Kubectl, diff Deployment Description: Create a Deployment with httpd image. Declare the same Deployment with a different image, busybox. Diff of live Deployment with declared Deployment MUST include the difference between live and declared image. */ framework.ConformanceIt("should check if kubectl diff finds a difference for Deployments", func() { - ginkgo.Skip("test skipped temporarily to enable 1.19 rebase to merge more quickly") - ginkgo.By("create deployment with httpd image") deployment := commonutils.SubstituteImageName(string(readTestFileOrDie(httpdDeployment3Filename))) framework.RunKubectlOrDieInput(ns, deployment, "create", "-f", "-") @@ -915,23 +910,22 @@ metadata: ginkgo.Describe("Kubectl server-side dry-run", func() { /* - Release : v1.19 + Release: v1.19 Testname: Kubectl, server-side dry-run Pod Description: The command 'kubectl run' must create a pod with the specified image name. After, the command 'kubectl replace --dry-run=server' should update the Pod with the new image name and server-side dry-run enabled. The image name must not change. */ framework.ConformanceIt("should check if kubectl can dry-run update Pods", func() { ginkgo.By("running the image " + httpdImage) podName := "e2e-test-httpd-pod" - nsFlag := fmt.Sprintf("--namespace=%v", ns) - framework.RunKubectlOrDie(ns, "run", podName, "--image="+httpdImage, "--labels=run="+podName, nsFlag) + framework.RunKubectlOrDie(ns, "run", podName, "--image="+httpdImage, "--labels=run="+podName) ginkgo.By("replace the image in the pod with server-side dry-run") - podJSON := framework.RunKubectlOrDie(ns, "get", "pod", podName, "-o", "json", nsFlag) + podJSON := framework.RunKubectlOrDie(ns, "get", "pod", podName, "-o", "json") podJSON = strings.Replace(podJSON, httpdImage, busyboxImage, 1) if !strings.Contains(podJSON, busyboxImage) { framework.Failf("Failed replacing image from %s to %s in:\n%s\n", httpdImage, busyboxImage, podJSON) } - framework.RunKubectlOrDieInput(ns, podJSON, "replace", "-f", "-", "--dry-run", "server", nsFlag) + framework.RunKubectlOrDieInput(ns, podJSON, "replace", "-f", "-", "--dry-run", "server") ginkgo.By("verifying the pod " + podName + " has the right image " + httpdImage) pod, err := c.CoreV1().Pods(ns).Get(context.TODO(), podName, metav1.GetOptions{}) @@ -943,7 +937,7 @@ metadata: framework.Failf("Failed creating pod with expected image %s", httpdImage) } - framework.RunKubectlOrDie(ns, "delete", "pods", podName, nsFlag) + framework.RunKubectlOrDie(ns, "delete", "pods", podName) }) }) @@ -1075,7 +1069,7 @@ metadata: ginkgo.Describe("Kubectl cluster-info", func() { /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, cluster info Description: Call kubectl to get cluster-info, output MUST contain cluster-info returned and Kubernetes Master SHOULD be running. */ @@ -1101,7 +1095,7 @@ metadata: ginkgo.Describe("Kubectl describe", func() { /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, describe pod or rc Description: Deploy an agnhost controller and an agnhost service. Kubectl describe pods SHOULD return the name, namespace, labels, state and other information as expected. Kubectl describe on rc, service, node and namespace SHOULD also return proper information. */ @@ -1109,16 +1103,15 @@ metadata: controllerJSON := commonutils.SubstituteImageName(string(readTestFileOrDie(agnhostControllerFilename))) serviceJSON := readTestFileOrDie(agnhostServiceFilename) - nsFlag := fmt.Sprintf("--namespace=%v", ns) - framework.RunKubectlOrDieInput(ns, controllerJSON, "create", "-f", "-", nsFlag) - framework.RunKubectlOrDieInput(ns, string(serviceJSON[:]), "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, controllerJSON, "create", "-f", "-") + framework.RunKubectlOrDieInput(ns, string(serviceJSON[:]), "create", "-f", "-") ginkgo.By("Waiting for Agnhost primary to start.") waitForOrFailWithDebug(1) // Pod forEachPod(func(pod v1.Pod) { - output := framework.RunKubectlOrDie(ns, "describe", "pod", pod.Name, nsFlag) + output := framework.RunKubectlOrDie(ns, "describe", "pod", pod.Name) requiredStrings := [][]string{ {"Name:", "agnhost-primary-"}, {"Namespace:", ns}, @@ -1149,10 +1142,10 @@ metadata: {"Pod Template:"}, {"Image:", agnhostImage}, {"Events:"}} - checkKubectlOutputWithRetry(ns, requiredStrings, "describe", "rc", "agnhost-primary", nsFlag) + checkKubectlOutputWithRetry(ns, requiredStrings, "describe", "rc", "agnhost-primary") // Service - output := framework.RunKubectlOrDie(ns, "describe", "service", "agnhost-primary", nsFlag) + output := framework.RunKubectlOrDie(ns, "describe", "service", "agnhost-primary") requiredStrings = [][]string{ {"Name:", "agnhost-primary"}, {"Namespace:", ns}, @@ -1205,9 +1198,8 @@ metadata: ginkgo.It("should check if kubectl describe prints relevant information for cronjob", func() { ginkgo.By("creating a cronjob") - nsFlag := fmt.Sprintf("--namespace=%v", ns) cronjobYaml := commonutils.SubstituteImageName(string(readTestFileOrDie("busybox-cronjob.yaml"))) - framework.RunKubectlOrDieInput(ns, cronjobYaml, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, cronjobYaml, "create", "-f", "-") ginkgo.By("waiting for cronjob to start.") err := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) { @@ -1220,7 +1212,7 @@ metadata: framework.ExpectNoError(err) ginkgo.By("verifying kubectl describe prints") - output := framework.RunKubectlOrDie(ns, "describe", "cronjob", "cronjob-test", nsFlag) + output := framework.RunKubectlOrDie(ns, "describe", "cronjob", "cronjob-test") requiredStrings := [][]string{ {"Name:", "cronjob-test"}, {"Namespace:", ns}, @@ -1242,20 +1234,19 @@ metadata: ginkgo.Describe("Kubectl expose", func() { /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, create service, replication controller Description: Create a Pod running agnhost listening to port 6379. Using kubectl expose the agnhost primary replication controllers at port 1234. Validate that the replication controller is listening on port 1234 and the target port is set to 6379, port that agnhost primary is listening. Using kubectl expose the agnhost primary as a service at port 2345. The service MUST be listening on port 2345 and the target port is set to 6379, port that agnhost primary is listening. */ framework.ConformanceIt("should create services for rc ", func() { controllerJSON := commonutils.SubstituteImageName(string(readTestFileOrDie(agnhostControllerFilename))) - nsFlag := fmt.Sprintf("--namespace=%v", ns) agnhostPort := 6379 ginkgo.By("creating Agnhost RC") framework.Logf("namespace %v", ns) - framework.RunKubectlOrDieInput(ns, controllerJSON, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, controllerJSON, "create", "-f", "-") // It may take a while for the pods to get registered in some cases, wait to be sure. ginkgo.By("Waiting for Agnhost primary to start.") @@ -1313,12 +1304,12 @@ metadata: } ginkgo.By("exposing RC") - framework.RunKubectlOrDie(ns, "expose", "rc", "agnhost-primary", "--name=rm2", "--port=1234", fmt.Sprintf("--target-port=%d", agnhostPort), nsFlag) + framework.RunKubectlOrDie(ns, "expose", "rc", "agnhost-primary", "--name=rm2", "--port=1234", fmt.Sprintf("--target-port=%d", agnhostPort)) e2enetwork.WaitForService(c, ns, "rm2", true, framework.Poll, framework.ServiceStartTimeout) validateService("rm2", 1234, framework.ServiceStartTimeout) ginkgo.By("exposing service") - framework.RunKubectlOrDie(ns, "expose", "service", "rm2", "--name=rm3", "--port=2345", fmt.Sprintf("--target-port=%d", agnhostPort), nsFlag) + framework.RunKubectlOrDie(ns, "expose", "service", "rm2", "--name=rm3", "--port=2345", fmt.Sprintf("--target-port=%d", agnhostPort)) e2enetwork.WaitForService(c, ns, "rm3", true, framework.Poll, framework.ServiceStartTimeout) validateService("rm3", 2345, framework.ServiceStartTimeout) }) @@ -1326,12 +1317,10 @@ metadata: ginkgo.Describe("Kubectl label", func() { var podYaml string - var nsFlag string ginkgo.BeforeEach(func() { ginkgo.By("creating the pod") podYaml = commonutils.SubstituteImageName(string(readTestFileOrDie("pause-pod.yaml.in"))) - nsFlag = fmt.Sprintf("--namespace=%v", ns) - framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-") framework.ExpectEqual(e2epod.CheckPodsRunningReady(c, ns, []string{pausePodName}, framework.PodStartTimeout), true) }) ginkgo.AfterEach(func() { @@ -1339,7 +1328,7 @@ metadata: }) /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, label update Description: When a Pod is running, update a Label using 'kubectl label' command. The label MUST be created in the Pod. A 'kubectl get pod' with -l option on the container MUST verify that the label can be read back. Use 'kubectl label label-' to remove the label. 'kubectl get pod' with -l option SHOULD not list the deleted label as the label is removed. */ @@ -1348,17 +1337,17 @@ metadata: labelValue := "testing-label-value" ginkgo.By("adding the label " + labelName + " with value " + labelValue + " to a pod") - framework.RunKubectlOrDie(ns, "label", "pods", pausePodName, labelName+"="+labelValue, nsFlag) + framework.RunKubectlOrDie(ns, "label", "pods", pausePodName, labelName+"="+labelValue) ginkgo.By("verifying the pod has the label " + labelName + " with the value " + labelValue) - output := framework.RunKubectlOrDie(ns, "get", "pod", pausePodName, "-L", labelName, nsFlag) + output := framework.RunKubectlOrDie(ns, "get", "pod", pausePodName, "-L", labelName) if !strings.Contains(output, labelValue) { framework.Failf("Failed updating label " + labelName + " to the pod " + pausePodName) } ginkgo.By("removing the label " + labelName + " of a pod") - framework.RunKubectlOrDie(ns, "label", "pods", pausePodName, labelName+"-", nsFlag) + framework.RunKubectlOrDie(ns, "label", "pods", pausePodName, labelName+"-") ginkgo.By("verifying the pod doesn't have the label " + labelName) - output = framework.RunKubectlOrDie(ns, "get", "pod", pausePodName, "-L", labelName, nsFlag) + output = framework.RunKubectlOrDie(ns, "get", "pod", pausePodName, "-L", labelName) if strings.Contains(output, labelValue) { framework.Failf("Failed removing label " + labelName + " of the pod " + pausePodName) } @@ -1367,12 +1356,10 @@ metadata: ginkgo.Describe("Kubectl copy", func() { var podYaml string - var nsFlag string ginkgo.BeforeEach(func() { ginkgo.By("creating the pod") - nsFlag = fmt.Sprintf("--namespace=%v", ns) podYaml = commonutils.SubstituteImageName(string(readTestFileOrDie("busybox-pod.yaml"))) - framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-") framework.ExpectEqual(e2epod.CheckPodsRunningReady(c, ns, []string{busyboxPodName}, framework.PodStartTimeout), true) }) ginkgo.AfterEach(func() { @@ -1380,7 +1367,7 @@ metadata: }) /* - Release : v1.12 + Release: v1.12 Testname: Kubectl, copy Description: When a Pod is running, copy a known file from it to a temporary local destination. */ @@ -1393,7 +1380,7 @@ metadata: } ginkgo.By("specifying a remote filepath " + podSource + " on the pod") - framework.RunKubectlOrDie(ns, "cp", podSource, tempDestination.Name(), nsFlag) + framework.RunKubectlOrDie(ns, "cp", podSource, tempDestination.Name()) ginkgo.By("verifying that the contents of the remote file " + podSource + " have been copied to a local file " + tempDestination.Name()) localData, err := ioutil.ReadAll(tempDestination) if err != nil { @@ -1406,21 +1393,19 @@ metadata: }) ginkgo.Describe("Kubectl logs", func() { - var nsFlag string podName := "logs-generator" containerName := "logs-generator" ginkgo.BeforeEach(func() { ginkgo.By("creating an pod") - nsFlag = fmt.Sprintf("--namespace=%v", ns) // Agnhost image generates logs for a total of 100 lines over 20s. - framework.RunKubectlOrDie(ns, "run", podName, "--image="+agnhostImage, nsFlag, "--", "logs-generator", "--log-lines-total", "100", "--run-duration", "20s") + framework.RunKubectlOrDie(ns, "run", podName, "--image="+agnhostImage, "--restart=Never", "--", "logs-generator", "--log-lines-total", "100", "--run-duration", "20s") }) ginkgo.AfterEach(func() { - framework.RunKubectlOrDie(ns, "delete", "pod", podName, nsFlag) + framework.RunKubectlOrDie(ns, "delete", "pod", podName) }) /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, logs Description: When a Pod is running then it MUST generate logs. Starting a Pod should have a expected log line. Also log command options MUST work as expected and described below. @@ -1447,19 +1432,19 @@ metadata: framework.ExpectNoError(err) ginkgo.By("limiting log lines") - out := framework.RunKubectlOrDie(ns, "logs", podName, containerName, nsFlag, "--tail=1") + out := framework.RunKubectlOrDie(ns, "logs", podName, containerName, "--tail=1") framework.Logf("got output %q", out) gomega.Expect(len(out)).NotTo(gomega.BeZero()) framework.ExpectEqual(len(lines(out)), 1) ginkgo.By("limiting log bytes") - out = framework.RunKubectlOrDie(ns, "logs", podName, containerName, nsFlag, "--limit-bytes=1") + out = framework.RunKubectlOrDie(ns, "logs", podName, containerName, "--limit-bytes=1") framework.Logf("got output %q", out) framework.ExpectEqual(len(lines(out)), 1) framework.ExpectEqual(len(out), 1) ginkgo.By("exposing timestamps") - out = framework.RunKubectlOrDie(ns, "logs", podName, containerName, nsFlag, "--tail=1", "--timestamps") + out = framework.RunKubectlOrDie(ns, "logs", podName, containerName, "--tail=1", "--timestamps") framework.Logf("got output %q", out) l := lines(out) framework.ExpectEqual(len(l), 1) @@ -1476,9 +1461,9 @@ metadata: // because the granularity is only 1 second and // it could end up rounding the wrong way. time.Sleep(2500 * time.Millisecond) // ensure that startup logs on the node are seen as older than 1s - recentOut := framework.RunKubectlOrDie(ns, "logs", podName, containerName, nsFlag, "--since=1s") + recentOut := framework.RunKubectlOrDie(ns, "logs", podName, containerName, "--since=1s") recent := len(strings.Split(recentOut, "\n")) - olderOut := framework.RunKubectlOrDie(ns, "logs", podName, containerName, nsFlag, "--since=24h") + olderOut := framework.RunKubectlOrDie(ns, "logs", podName, containerName, "--since=24h") older := len(strings.Split(olderOut, "\n")) gomega.Expect(recent).To(gomega.BeNumerically("<", older), "expected recent(%v) to be less than older(%v)\nrecent lines:\n%v\nolder lines:\n%v\n", recent, older, recentOut, olderOut) }) @@ -1486,20 +1471,19 @@ metadata: ginkgo.Describe("Kubectl patch", func() { /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, patch to annotate Description: Start running agnhost and a replication controller. When the pod is running, using 'kubectl patch' command add annotations. The annotation MUST be added to running pods and SHOULD be able to read added annotations from each of the Pods running under the replication controller. */ framework.ConformanceIt("should add annotations for pods in rc ", func() { controllerJSON := commonutils.SubstituteImageName(string(readTestFileOrDie(agnhostControllerFilename))) - nsFlag := fmt.Sprintf("--namespace=%v", ns) ginkgo.By("creating Agnhost RC") - framework.RunKubectlOrDieInput(ns, controllerJSON, "create", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, controllerJSON, "create", "-f", "-") ginkgo.By("Waiting for Agnhost primary to start.") waitForOrFailWithDebug(1) ginkgo.By("patching all pods") forEachPod(func(pod v1.Pod) { - framework.RunKubectlOrDie(ns, "patch", "pod", pod.Name, nsFlag, "-p", "{\"metadata\":{\"annotations\":{\"x\":\"y\"}}}") + framework.RunKubectlOrDie(ns, "patch", "pod", pod.Name, "-p", "{\"metadata\":{\"annotations\":{\"x\":\"y\"}}}") }) ginkgo.By("checking annotations") @@ -1520,7 +1504,7 @@ metadata: ginkgo.Describe("Kubectl version", func() { /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, version Description: The command 'kubectl version' MUST return the major, minor versions, GitCommit, etc of the Client and the Server that the kubectl is configured to connect to. */ @@ -1536,26 +1520,24 @@ metadata: }) ginkgo.Describe("Kubectl run pod", func() { - var nsFlag string var podName string ginkgo.BeforeEach(func() { - nsFlag = fmt.Sprintf("--namespace=%v", ns) podName = "e2e-test-httpd-pod" }) ginkgo.AfterEach(func() { - framework.RunKubectlOrDie(ns, "delete", "pods", podName, nsFlag) + framework.RunKubectlOrDie(ns, "delete", "pods", podName) }) /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, run pod Description: Command 'kubectl run' MUST create a pod, when a image name is specified in the run command. After the run command there SHOULD be a pod that should exist with one container running the specified image. */ framework.ConformanceIt("should create a pod from an image when restart is Never ", func() { ginkgo.By("running the image " + httpdImage) - framework.RunKubectlOrDie(ns, "run", podName, "--restart=Never", "--image="+httpdImage, nsFlag) + framework.RunKubectlOrDie(ns, "run", podName, "--restart=Never", "--image="+httpdImage) ginkgo.By("verifying the pod " + podName + " was created") pod, err := c.CoreV1().Pods(ns).Get(context.TODO(), podName, metav1.GetOptions{}) if err != nil { @@ -1572,26 +1554,24 @@ metadata: }) ginkgo.Describe("Kubectl replace", func() { - var nsFlag string var podName string ginkgo.BeforeEach(func() { - nsFlag = fmt.Sprintf("--namespace=%v", ns) podName = "e2e-test-httpd-pod" }) ginkgo.AfterEach(func() { - framework.RunKubectlOrDie(ns, "delete", "pods", podName, nsFlag) + framework.RunKubectlOrDie(ns, "delete", "pods", podName) }) /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, replace Description: Command 'kubectl replace' on a existing Pod with a new spec MUST update the image of the container running in the Pod. A -f option to 'kubectl replace' SHOULD force to re-create the resource. The new Pod SHOULD have the container with new change to the image. */ framework.ConformanceIt("should update a single-container pod's image ", func() { ginkgo.By("running the image " + httpdImage) - framework.RunKubectlOrDie(ns, "run", podName, "--image="+httpdImage, "--labels=run="+podName, nsFlag) + framework.RunKubectlOrDie(ns, "run", podName, "--image="+httpdImage, "--labels=run="+podName) ginkgo.By("verifying the pod " + podName + " is running") label := labels.SelectorFromSet(labels.Set(map[string]string{"run": podName})) @@ -1601,14 +1581,14 @@ metadata: } ginkgo.By("verifying the pod " + podName + " was created") - podJSON := framework.RunKubectlOrDie(ns, "get", "pod", podName, nsFlag, "-o", "json") + podJSON := framework.RunKubectlOrDie(ns, "get", "pod", podName, "-o", "json") if !strings.Contains(podJSON, podName) { framework.Failf("Failed to find pod %s in [%s]", podName, podJSON) } ginkgo.By("replace the image in the pod") podJSON = strings.Replace(podJSON, httpdImage, busyboxImage, 1) - framework.RunKubectlOrDieInput(ns, podJSON, "replace", "-f", "-", nsFlag) + framework.RunKubectlOrDieInput(ns, podJSON, "replace", "-f", "-") ginkgo.By("verifying the pod " + podName + " has the right image " + busyboxImage) pod, err := c.CoreV1().Pods(ns).Get(context.TODO(), podName, metav1.GetOptions{}) @@ -1625,7 +1605,7 @@ metadata: ginkgo.Describe("Proxy server", func() { // TODO: test proxy options (static, prefix, etc) /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, proxy port zero Description: Start a proxy server on port zero by running 'kubectl proxy' with --port=0. Call the proxy server by requesting api versions from unix socket. The proxy server MUST provide at least one version string. */ @@ -1650,7 +1630,7 @@ metadata: }) /* - Release : v1.9 + Release: v1.9 Testname: Kubectl, proxy socket Description: Start a proxy server on by running 'kubectl proxy' with --unix-socket=. Call the proxy server by requesting api versions from http://locahost:0/api. The proxy server MUST provide at least one version string */ @@ -1788,11 +1768,10 @@ metadata: ginkgo.Describe("Kubectl create quota", func() { ginkgo.It("should create a quota without scopes", func() { - nsFlag := fmt.Sprintf("--namespace=%v", ns) quotaName := "million" ginkgo.By("calling kubectl quota") - framework.RunKubectlOrDie(ns, "create", "quota", quotaName, "--hard=pods=1000000,services=1000000", nsFlag) + framework.RunKubectlOrDie(ns, "create", "quota", quotaName, "--hard=pods=1000000,services=1000000") ginkgo.By("verifying that the quota was created") quota, err := c.CoreV1().ResourceQuotas(ns).Get(context.TODO(), quotaName, metav1.GetOptions{}) @@ -1817,11 +1796,10 @@ metadata: }) ginkgo.It("should create a quota with scopes", func() { - nsFlag := fmt.Sprintf("--namespace=%v", ns) quotaName := "scopes" ginkgo.By("calling kubectl quota") - framework.RunKubectlOrDie(ns, "create", "quota", quotaName, "--hard=pods=1000000", "--scopes=BestEffort,NotTerminating", nsFlag) + framework.RunKubectlOrDie(ns, "create", "quota", quotaName, "--hard=pods=1000000", "--scopes=BestEffort,NotTerminating") ginkgo.By("verifying that the quota was created") quota, err := c.CoreV1().ResourceQuotas(ns).Get(context.TODO(), quotaName, metav1.GetOptions{}) @@ -1845,11 +1823,10 @@ metadata: }) ginkgo.It("should reject quota with invalid scopes", func() { - nsFlag := fmt.Sprintf("--namespace=%v", ns) quotaName := "scopes" ginkgo.By("calling kubectl quota") - out, err := framework.RunKubectl(ns, "create", "quota", quotaName, "--hard=hard=pods=1000000", "--scopes=Foo", nsFlag) + out, err := framework.RunKubectl(ns, "create", "quota", quotaName, "--hard=hard=pods=1000000", "--scopes=Foo") if err == nil { framework.Failf("Expected kubectl to fail, but it succeeded: %s", out) } @@ -2155,19 +2132,18 @@ func startLocalProxy() (srv *httptest.Server, logs *bytes.Buffer) { // createApplyCustomResource asserts that given CustomResource be created and applied // without being rejected by client-side validation func createApplyCustomResource(resource, namespace, name string, crd *crd.TestCrd) error { - ns := fmt.Sprintf("--namespace=%v", namespace) ginkgo.By("successfully create CR") - if _, err := framework.RunKubectlInput(namespace, resource, ns, "create", "--validate=true", "-f", "-"); err != nil { - return fmt.Errorf("failed to create CR %s in namespace %s: %v", resource, ns, err) + if _, err := framework.RunKubectlInput(namespace, resource, "create", "--validate=true", "-f", "-"); err != nil { + return fmt.Errorf("failed to create CR %s in namespace %s: %v", resource, namespace, err) } - if _, err := framework.RunKubectl(namespace, ns, "delete", crd.Crd.Spec.Names.Plural, name); err != nil { + if _, err := framework.RunKubectl(namespace, "delete", crd.Crd.Spec.Names.Plural, name); err != nil { return fmt.Errorf("failed to delete CR %s: %v", name, err) } ginkgo.By("successfully apply CR") - if _, err := framework.RunKubectlInput(namespace, resource, ns, "apply", "--validate=true", "-f", "-"); err != nil { - return fmt.Errorf("failed to apply CR %s in namespace %s: %v", resource, ns, err) + if _, err := framework.RunKubectlInput(namespace, resource, "apply", "--validate=true", "-f", "-"); err != nil { + return fmt.Errorf("failed to apply CR %s in namespace %s: %v", resource, namespace, err) } - if _, err := framework.RunKubectl(namespace, ns, "delete", crd.Crd.Spec.Names.Plural, name); err != nil { + if _, err := framework.RunKubectl(namespace, "delete", crd.Crd.Spec.Names.Plural, name); err != nil { return fmt.Errorf("failed to delete CR %s: %v", name, err) } return nil @@ -2202,7 +2178,7 @@ func validateController(c clientset.Interface, containerImage string, replicas i ginkgo.By(fmt.Sprintf("waiting for all containers in %s pods to come up.", testname)) //testname should be selector waitLoop: for start := time.Now(); time.Since(start) < framework.PodStartTimeout; time.Sleep(5 * time.Second) { - getPodsOutput := framework.RunKubectlOrDie(ns, "get", "pods", "-o", "template", getPodsTemplate, "-l", testname, fmt.Sprintf("--namespace=%v", ns)) + getPodsOutput := framework.RunKubectlOrDie(ns, "get", "pods", "-o", "template", getPodsTemplate, "-l", testname) pods := strings.Fields(getPodsOutput) if numPods := len(pods); numPods != replicas { ginkgo.By(fmt.Sprintf("Replicas for %s: expected=%d actual=%d", testname, replicas, numPods)) @@ -2210,13 +2186,13 @@ waitLoop: } var runningPods []string for _, podID := range pods { - running := framework.RunKubectlOrDie(ns, "get", "pods", podID, "-o", "template", getContainerStateTemplate, fmt.Sprintf("--namespace=%v", ns)) + running := framework.RunKubectlOrDie(ns, "get", "pods", podID, "-o", "template", getContainerStateTemplate) if running != "true" { framework.Logf("%s is created but not running", podID) continue waitLoop } - currentImage := framework.RunKubectlOrDie(ns, "get", "pods", podID, "-o", "template", getImageTemplate, fmt.Sprintf("--namespace=%v", ns)) + currentImage := framework.RunKubectlOrDie(ns, "get", "pods", podID, "-o", "template", getImageTemplate) currentImage = trimDockerRegistry(currentImage) if currentImage != containerImage { framework.Logf("%s is created but running wrong image; expected: %s, actual: %s", podID, containerImage, currentImage) diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/BUILD b/vendor/k8s.io/kubernetes/test/e2e/network/BUILD index 49fce64e0d60..cd255fe8d4e7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/network/BUILD @@ -64,6 +64,7 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library", + "//staging/src/k8s.io/client-go/tools/watch:go_default_library", "//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library", "//staging/src/k8s.io/client-go/util/retry:go_default_library", "//staging/src/k8s.io/client-go/util/workqueue:go_default_library", @@ -73,6 +74,7 @@ go_library( "//test/e2e/framework/auth:go_default_library", "//test/e2e/framework/deployment:go_default_library", "//test/e2e/framework/endpoints:go_default_library", + "//test/e2e/framework/endpointslice:go_default_library", "//test/e2e/framework/ingress:go_default_library", "//test/e2e/framework/kubesystem:go_default_library", "//test/e2e/framework/network:go_default_library", diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/dns.go b/vendor/k8s.io/kubernetes/test/e2e/network/dns.go index a56eb1b3507f..6d47cc9afdc1 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/dns.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/dns.go @@ -40,7 +40,7 @@ var _ = SIGDescribe("DNS", func() { f := framework.NewDefaultFramework("dns") /* - Release : v1.9 + Release: v1.9 Testname: DNS, cluster Description: When a Pod is created, the pod MUST be able to resolve cluster dns entries such as kubernetes.default via DNS. */ @@ -107,7 +107,7 @@ var _ = SIGDescribe("DNS", func() { }) /* - Release : v1.14 + Release: v1.14 Testname: DNS, cluster Description: When a Pod is created, the pod MUST be able to resolve cluster dns entries such as kubernetes.default via /etc/hosts. */ @@ -127,7 +127,7 @@ var _ = SIGDescribe("DNS", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: DNS, services Description: When a headless service is created, the service MUST be able to resolve all the required service endpoints. When the service is created, any pod in the same namespace must be able to resolve the service by all of the expected DNS names. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/dns_configmap.go b/vendor/k8s.io/kubernetes/test/e2e/network/dns_configmap.go index 0596b3992efc..e73b117041fc 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/dns_configmap.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/dns_configmap.go @@ -26,7 +26,6 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/kubernetes/test/e2e/framework" e2eservice "k8s.io/kubernetes/test/e2e/framework/service" - e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" "github.com/onsi/ginkgo" ) @@ -484,14 +483,14 @@ func (t *dnsExternalNameTest) run(isIPv6 bool) { t.restoreDNSConfigMap(originalConfigMapData) } -var _ = SIGDescribe("DNS configMap nameserver [IPv4]", func() { +var _ = SIGDescribe("DNS configMap nameserver", func() { ginkgo.Context("Change stubDomain", func() { nsTest := &dnsNameserverTest{dnsTestCommon: newDNSTestCommon()} ginkgo.It("should be able to change stubDomain configuration [Slow][Serial]", func() { nsTest.c = nsTest.f.ClientSet - nsTest.run(false) + nsTest.run(framework.TestContext.ClusterIsIPv6()) }) }) @@ -500,7 +499,7 @@ var _ = SIGDescribe("DNS configMap nameserver [IPv4]", func() { ginkgo.It("should forward PTR records lookup to upstream nameserver [Slow][Serial]", func() { fwdTest.c = fwdTest.f.ClientSet - fwdTest.run(false) + fwdTest.run(framework.TestContext.ClusterIsIPv6()) }) }) @@ -509,42 +508,7 @@ var _ = SIGDescribe("DNS configMap nameserver [IPv4]", func() { ginkgo.It("should forward externalname lookup to upstream nameserver [Slow][Serial]", func() { externalNameTest.c = externalNameTest.f.ClientSet - externalNameTest.run(false) - }) - }) -}) - -var _ = SIGDescribe("DNS configMap nameserver [Feature:Networking-IPv6] [LinuxOnly]", func() { - - ginkgo.BeforeEach(func() { - // IPv6 is not supported on Windows. - e2eskipper.SkipIfNodeOSDistroIs("windows") - }) - - ginkgo.Context("Change stubDomain", func() { - nsTest := &dnsNameserverTest{dnsTestCommon: newDNSTestCommon()} - - ginkgo.It("should be able to change stubDomain configuration [Slow][Serial]", func() { - nsTest.c = nsTest.f.ClientSet - nsTest.run(true) - }) - }) - - ginkgo.Context("Forward PTR lookup", func() { - fwdTest := &dnsPtrFwdTest{dnsTestCommon: newDNSTestCommon()} - - ginkgo.It("should forward PTR records lookup to upstream nameserver [Slow][Serial]", func() { - fwdTest.c = fwdTest.f.ClientSet - fwdTest.run(true) - }) - }) - - ginkgo.Context("Forward external name lookup", func() { - externalNameTest := &dnsExternalNameTest{dnsTestCommon: newDNSTestCommon()} - - ginkgo.It("should forward externalname lookup to upstream nameserver [Slow][Serial]", func() { - externalNameTest.c = externalNameTest.f.ClientSet - externalNameTest.run(true) + externalNameTest.run(framework.TestContext.ClusterIsIPv6()) }) }) }) diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/dns_scale_records.go b/vendor/k8s.io/kubernetes/test/e2e/network/dns_scale_records.go index f2820a806674..b533bea1d172 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/dns_scale_records.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/dns_scale_records.go @@ -60,6 +60,7 @@ var _ = SIGDescribe("[Feature:PerformanceDNS][Serial]", func() { for i := 0; i < numNs; i++ { ns, _ := f.CreateNamespace(f.BaseName, nil) namespaces = append(namespaces, ns.Name) + f.AddNamespacesToDelete(ns) } services := generateServicesInNamespaces(namespaces, maxServicesPerCluster) diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/endpointslice.go b/vendor/k8s.io/kubernetes/test/e2e/network/endpointslice.go index ca5a987bba53..f22f6b112fa2 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/endpointslice.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/endpointslice.go @@ -18,6 +18,7 @@ package network import ( "context" + "encoding/json" "fmt" "time" @@ -26,6 +27,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/test/e2e/framework" @@ -49,14 +51,14 @@ var _ = SIGDescribe("EndpointSlice", func() { namespace := "default" name := "kubernetes" endpoints, err := cs.CoreV1().Endpoints(namespace).Get(context.TODO(), name, metav1.GetOptions{}) - framework.ExpectNoError(err) + framework.ExpectNoError(err, "error creating Endpoints resource") if len(endpoints.Subsets) != 1 { framework.Failf("Expected 1 subset in endpoints, got %d: %#v", len(endpoints.Subsets), endpoints.Subsets) } endpointSubset := endpoints.Subsets[0] endpointSlice, err := cs.DiscoveryV1beta1().EndpointSlices(namespace).Get(context.TODO(), name, metav1.GetOptions{}) - framework.ExpectNoError(err) + framework.ExpectNoError(err, "error creating EndpointSlice resource") if len(endpointSlice.Ports) != len(endpointSubset.Ports) { framework.Failf("Expected EndpointSlice to have %d ports, got %d: %#v", len(endpointSubset.Ports), len(endpointSlice.Ports), endpointSlice.Ports) } @@ -85,7 +87,7 @@ var _ = SIGDescribe("EndpointSlice", func() { }) // Expect Endpoints resource to be created. - if err := wait.PollImmediate(2*time.Second, 12*time.Second, func() (bool, error) { + if err := wait.PollImmediate(2*time.Second, wait.ForeverTestTimeout, func() (bool, error) { _, err := cs.CoreV1().Endpoints(svc.Namespace).Get(context.TODO(), svc.Name, metav1.GetOptions{}) if err != nil { return false, nil @@ -97,7 +99,7 @@ var _ = SIGDescribe("EndpointSlice", func() { // Expect EndpointSlice resource to be created. var endpointSlice discoveryv1beta1.EndpointSlice - if err := wait.PollImmediate(2*time.Second, 12*time.Second, func() (bool, error) { + if err := wait.PollImmediate(2*time.Second, wait.ForeverTestTimeout, func() (bool, error) { endpointSliceList, err := cs.DiscoveryV1beta1().EndpointSlices(svc.Namespace).List(context.TODO(), metav1.ListOptions{ LabelSelector: "kubernetes.io/service-name=" + svc.Name, }) @@ -126,10 +128,10 @@ var _ = SIGDescribe("EndpointSlice", func() { } err := cs.CoreV1().Services(svc.Namespace).Delete(context.TODO(), svc.Name, metav1.DeleteOptions{}) - framework.ExpectNoError(err) + framework.ExpectNoError(err, "error deleting Service") // Expect Endpoints resource to be deleted when Service is. - if err := wait.PollImmediate(2*time.Second, 12*time.Second, func() (bool, error) { + if err := wait.PollImmediate(2*time.Second, wait.ForeverTestTimeout, func() (bool, error) { _, err := cs.CoreV1().Endpoints(svc.Namespace).Get(context.TODO(), svc.Name, metav1.GetOptions{}) if err != nil { if apierrors.IsNotFound(err) { @@ -143,7 +145,7 @@ var _ = SIGDescribe("EndpointSlice", func() { } // Expect EndpointSlice resource to be deleted when Service is. - if err := wait.PollImmediate(2*time.Second, 12*time.Second, func() (bool, error) { + if err := wait.PollImmediate(2*time.Second, wait.ForeverTestTimeout, func() (bool, error) { endpointSliceList, err := cs.DiscoveryV1beta1().EndpointSlices(svc.Namespace).List(context.TODO(), metav1.ListOptions{ LabelSelector: "kubernetes.io/service-name=" + svc.Name, }) @@ -218,7 +220,8 @@ var _ = SIGDescribe("EndpointSlice", func() { Name: "example-int-port", }, Spec: v1.ServiceSpec{ - Selector: map[string]string{labelPod1: labelValue}, + Selector: map[string]string{labelPod1: labelValue}, + PublishNotReadyAddresses: true, Ports: []v1.ServicePort{{ Name: "example", Port: 80, @@ -233,7 +236,8 @@ var _ = SIGDescribe("EndpointSlice", func() { Name: "example-named-port", }, Spec: v1.ServiceSpec{ - Selector: map[string]string{labelShared12: labelValue}, + Selector: map[string]string{labelShared12: labelValue}, + PublishNotReadyAddresses: true, Ports: []v1.ServicePort{{ Name: "http", Port: 80, @@ -248,7 +252,8 @@ var _ = SIGDescribe("EndpointSlice", func() { Name: "example-no-match", }, Spec: v1.ServiceSpec{ - Selector: map[string]string{labelPod3: labelValue}, + Selector: map[string]string{labelPod3: labelValue}, + PublishNotReadyAddresses: true, Ports: []v1.ServicePort{{ Name: "example-no-match", Port: 80, @@ -259,30 +264,26 @@ var _ = SIGDescribe("EndpointSlice", func() { }) err := wait.Poll(5*time.Second, 3*time.Minute, func() (bool, error) { - if !podClient.PodIsReady(pod1.Name) { - framework.Logf("Pod 1 not ready yet") - return false, nil - } - - if !podClient.PodIsReady(pod2.Name) { - framework.Logf("Pod 2 not ready yet") - return false, nil - } - var err error pod1, err = podClient.Get(context.TODO(), pod1.Name, metav1.GetOptions{}) if err != nil { return false, err } + if len(pod1.Status.PodIPs) == 0 { + return false, nil + } pod2, err = podClient.Get(context.TODO(), pod2.Name, metav1.GetOptions{}) if err != nil { return false, err } + if len(pod2.Status.PodIPs) == 0 { + return false, nil + } return true, nil }) - framework.ExpectNoError(err) + framework.ExpectNoError(err, "timed out waiting for Pods to have IPs assigned") ginkgo.By("referencing a single matching pod") expectEndpointsAndSlices(cs, f.Namespace.Name, svc1, []*v1.Pod{pod1}, 1, 1, false) @@ -312,13 +313,12 @@ func expectEndpointsAndSlices(cs clientset.Interface, ns string, svc *v1.Service if err := wait.PollImmediate(5*time.Second, 2*time.Minute, func() (bool, error) { endpointSlicesFound, hasMatchingSlices := hasMatchingEndpointSlices(cs, ns, svc.Name, len(pods), numSlices) if !hasMatchingSlices { - framework.Logf("Matching EndpointSlices not found") return false, nil } endpointSlices = endpointSlicesFound return true, nil }); err != nil { - framework.Failf("Timed out waiting for matching EndpointSlices to exist: %v", err) + framework.Failf("Timed out waiting for EndpointSlices to match expectations: %v", err) } endpoints := &v1.Endpoints{} @@ -331,7 +331,7 @@ func expectEndpointsAndSlices(cs clientset.Interface, ns string, svc *v1.Service endpoints = endpointsFound return true, nil }); err != nil { - framework.Failf("Timed out waiting for matching Endpoints to exist: %v", err) + framework.Failf("Timed out waiting for Endpoints to match expectations: %v", err) } podsByIP := map[string]*v1.Pod{} @@ -407,9 +407,13 @@ func expectEndpointsAndSlices(cs clientset.Interface, ns string, svc *v1.Service framework.Failf("Expected 1 EndpointSlice, got %d", len(endpointSlices)) } - totalEndpointSliceAddresses := 0 + // Use a set for deduping values. Duplicate addresses are technically valid + // here although rare. + esAddresses := sets.NewString() for _, endpointSlice := range endpointSlices { - totalEndpointSliceAddresses += len(endpointSlice.Endpoints) + for _, endpoint := range endpointSlice.Endpoints { + esAddresses.Insert(endpoint.Addresses[0]) + } if len(pods) == 0 && len(endpointSlice.Ports) != 0 { framework.Failf("Expected EndpointSlice to have 0 ports, got %d", len(endpointSlice.Ports)) } @@ -464,8 +468,8 @@ func expectEndpointsAndSlices(cs clientset.Interface, ns string, svc *v1.Service } } - if len(pods) != totalEndpointSliceAddresses { - framework.Failf("Expected %d addresses, got %d", len(pods), totalEndpointSliceAddresses) + if len(pods) != esAddresses.Len() { + framework.Failf("Expected %d addresses, got %d", len(pods), esAddresses.Len()) } } @@ -493,9 +497,21 @@ func hasMatchingEndpointSlices(cs clientset.Interface, ns, svcName string, numEn framework.Logf("EndpointSlice for Service %s/%s not found", ns, svcName) return []discoveryv1beta1.EndpointSlice{}, false } - if len(esList.Items) != numSlices { - framework.Logf("Expected %d EndpointSlices for Service %s/%s, got %d", numSlices, ns, svcName, len(esList.Items)) - return []discoveryv1beta1.EndpointSlice{}, false + // In some cases the EndpointSlice controller will create more + // EndpointSlices than necessary resulting in some duplication. This is + // valid and tests should only fail here if less EndpointSlices than + // expected are added. + if len(esList.Items) < numSlices { + framework.Logf("Expected at least %d EndpointSlices for Service %s/%s, got %d", numSlices, ns, svcName, len(esList.Items)) + for i, epSlice := range esList.Items { + epsData, err := json.Marshal(epSlice) + if err != nil { + framework.Logf("Error marshaling JSON for EndpointSlice: %v", err) + } else { + framework.Logf("%d - %v", i, string(epsData)) + } + } + return esList.Items, false } actualNumEndpoints := 0 @@ -504,7 +520,7 @@ func hasMatchingEndpointSlices(cs clientset.Interface, ns, svcName string, numEn } if actualNumEndpoints != numEndpoints { framework.Logf("EndpointSlices for %s/%s Service have %d/%d endpoints", ns, svcName, actualNumEndpoints, numEndpoints) - return []discoveryv1beta1.EndpointSlice{}, false + return esList.Items, false } return esList.Items, true @@ -560,6 +576,6 @@ func ensurePodTargetRef(pod *v1.Pod, targetRef *v1.ObjectReference) { // createServiceReportErr creates a Service and reports any associated error. func createServiceReportErr(cs clientset.Interface, ns string, service *v1.Service) *v1.Service { svc, err := cs.CoreV1().Services(ns).Create(context.TODO(), service, metav1.CreateOptions{}) - framework.ExpectNoError(err) + framework.ExpectNoError(err, "error deleting Service") return svc } diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/ingress.go b/vendor/k8s.io/kubernetes/test/e2e/network/ingress.go index 9e9cfd7c7341..5a1c869db70c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/ingress.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/ingress.go @@ -136,6 +136,8 @@ var _ = SIGDescribe("Loadbalancing: L7", func() { ginkgo.It("should support multiple TLS certs", func() { ginkgo.By("Creating an ingress with no certs.") + + _ = gceController.CreateStaticIP(ns) jig.CreateIngress(filepath.Join(e2eingress.IngressManifestPath, "multiple-certs"), ns, map[string]string{ e2eingress.IngressStaticIPKey: ns, }, map[string]string{}) diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/ingressclass.go b/vendor/k8s.io/kubernetes/test/e2e/network/ingressclass.go index 421699ba7d63..29316662e10a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/ingressclass.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/ingressclass.go @@ -43,7 +43,7 @@ var _ = SIGDescribe("IngressClass [Feature:Ingress]", func() { cs = f.ClientSet }) - ginkgo.It("should set default value on new IngressClass", func() { + ginkgo.It("should set default value on new IngressClass [Serial]", func() { ingressClass1, err := createIngressClass(cs, "ingressclass1", true, f.UniqueName) framework.ExpectNoError(err) defer deleteIngressClass(cs, ingressClass1.Name) @@ -58,7 +58,7 @@ var _ = SIGDescribe("IngressClass [Feature:Ingress]", func() { } }) - ginkgo.It("should not set default value if no default IngressClass", func() { + ginkgo.It("should not set default value if no default IngressClass [Serial]", func() { ingressClass1, err := createIngressClass(cs, "ingressclass1", false, f.UniqueName) framework.ExpectNoError(err) defer deleteIngressClass(cs, ingressClass1.Name) @@ -71,7 +71,7 @@ var _ = SIGDescribe("IngressClass [Feature:Ingress]", func() { } }) - ginkgo.It("should prevent Ingress creation if more than 1 IngressClass marked as default", func() { + ginkgo.It("should prevent Ingress creation if more than 1 IngressClass marked as default [Serial]", func() { ingressClass1, err := createIngressClass(cs, "ingressclass1", true, f.UniqueName) framework.ExpectNoError(err) defer deleteIngressClass(cs, ingressClass1.Name) @@ -212,11 +212,11 @@ var _ = SIGDescribe("IngressClass API", func() { // IngressClass resource create/read/update/watch verbs ginkgo.By("creating") - ingressClass1, err := createIngressClass(cs, "ingressclass1", true, f.UniqueName) + ingressClass1, err := createIngressClass(cs, "ingressclass1", false, f.UniqueName) framework.ExpectNoError(err) - _, err = createIngressClass(cs, "ingressclass2", true, f.UniqueName) + _, err = createIngressClass(cs, "ingressclass2", false, f.UniqueName) framework.ExpectNoError(err) - _, err = createIngressClass(cs, "ingressclass3", true, f.UniqueName) + _, err = createIngressClass(cs, "ingressclass3", false, f.UniqueName) framework.ExpectNoError(err) ginkgo.By("getting") diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/kube_proxy.go b/vendor/k8s.io/kubernetes/test/e2e/network/kube_proxy.go index 439b8015dc26..aaff522ed0e8 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/kube_proxy.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/kube_proxy.go @@ -313,7 +313,7 @@ var _ = SIGDescribe("Network", func() { Name: "startup-script", Image: imageutils.GetE2EImage(imageutils.BusyBox), Command: []string{ - "bash", "-c", "while true; do sleep 2; nc boom-server 9000& done", + "sh", "-c", "while true; do sleep 2; nc boom-server 9000& done", }, }, }, diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/no_snat.go b/vendor/k8s.io/kubernetes/test/e2e/network/no_snat.go index 48320e0464df..7d415f27a3c5 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/no_snat.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/no_snat.go @@ -19,116 +19,43 @@ package network import ( "context" "fmt" - "io/ioutil" - "net/http" - "strconv" - "strings" + "net" "time" + "github.com/onsi/ginkgo" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/kubernetes/test/e2e/framework" - - "github.com/onsi/ginkgo" + "k8s.io/kubernetes/test/e2e/framework" imageutils "k8s.io/kubernetes/test/utils/image" ) const ( - testPodPort = 8080 - - testProxyPort = 31235 // Firewall rule allows external traffic on ports 30000-32767. I just picked a random one. + testPodPort = "8080" + noSNATTestName = "no-snat-test" ) var ( testPod = v1.Pod{ ObjectMeta: metav1.ObjectMeta{ - GenerateName: "no-snat-test", + GenerateName: noSNATTestName, Labels: map[string]string{ - "no-snat-test": "", + noSNATTestName: "", }, }, Spec: v1.PodSpec{ Containers: []v1.Container{ { - Name: "no-snat-test", + Name: noSNATTestName, Image: imageutils.GetE2EImage(imageutils.Agnhost), - Args: []string{"no-snat-test", "--port", strconv.Itoa(testPodPort)}, - Env: []v1.EnvVar{ - { - Name: "POD_IP", - ValueFrom: &v1.EnvVarSource{FieldRef: &v1.ObjectFieldSelector{FieldPath: "status.podIP"}}, - }, - }, - }, - }, - }, - } - - testProxyPod = v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "no-snat-test-proxy", - }, - Spec: v1.PodSpec{ - HostNetwork: true, - Containers: []v1.Container{ - { - Name: "no-snat-test-proxy", - Image: imageutils.GetE2EImage(imageutils.Agnhost), - Args: []string{"no-snat-test-proxy", "--port", strconv.Itoa(testProxyPort)}, - Ports: []v1.ContainerPort{ - { - ContainerPort: testProxyPort, - HostPort: testProxyPort, - }, - }, + Args: []string{"netexec", "--http-port", testPodPort}, }, }, }, } ) -// Produces a pod spec that passes nip as NODE_IP env var using downward API -func newTestPod(nodename string, nip string) *v1.Pod { - pod := testPod - nodeIP := v1.EnvVar{ - Name: "NODE_IP", - Value: nip, - } - pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, nodeIP) - pod.Spec.NodeName = nodename - return &pod -} - -func newTestProxyPod(nodename string) *v1.Pod { - pod := testProxyPod - pod.Spec.NodeName = nodename - return &pod -} - -func getIP(iptype v1.NodeAddressType, node *v1.Node) (string, error) { - for _, addr := range node.Status.Addresses { - if addr.Type == iptype { - return addr.Address, nil - } - } - return "", fmt.Errorf("did not find %s on Node", iptype) -} - -func getSchedulable(nodes []v1.Node) (*v1.Node, error) { - for _, node := range nodes { - if !node.Spec.Unschedulable { - return &node, nil - } - } - return nil, fmt.Errorf("all Nodes were unschedulable") -} - -func checknosnatURL(proxy, pip string, ips []string) string { - return fmt.Sprintf("http://%s/checknosnat?target=%s&ips=%s", proxy, pip, strings.Join(ips, ",")) -} - // This test verifies that a Pod on each node in a cluster can talk to Pods on every other node without SNAT. // We use the [Feature:NoSNAT] tag so that most jobs will skip this test by default. var _ = SIGDescribe("NoSNAT [Feature:NoSNAT] [Slow]", func() { @@ -144,39 +71,15 @@ var _ = SIGDescribe("NoSNAT [Feature:NoSNAT] [Slow]", func() { framework.ExpectNotEqual(len(nodes.Items), 0, "no Nodes in the cluster") for _, node := range nodes.Items { - // find the Node's internal ip address to feed to the Pod - inIP, err := getIP(v1.NodeInternalIP, &node) - framework.ExpectNoError(err) - - // target Pod at Node and feed Pod Node's InternalIP - pod := newTestPod(node.Name, inIP) - _, err = pc.Create(context.TODO(), pod, metav1.CreateOptions{}) + // target Pod at Node + testPod.Spec.NodeName = node.Name + _, err = pc.Create(context.TODO(), &testPod, metav1.CreateOptions{}) framework.ExpectNoError(err) } - // In some (most?) scenarios, the test harness doesn't run in the same network as the Pods, - // which means it can't query Pods using their cluster-internal IPs. To get around this, - // we create a Pod in a Node's host network, and have that Pod serve on a specific port of that Node. - // We can then ask this proxy Pod to query the internal endpoints served by the test Pods. - - // Find the first schedulable node; masters are marked unschedulable. We don't put the proxy on the master - // because in some (most?) deployments firewall rules don't allow external traffic to hit ports 30000-32767 - // on the master, but do allow this on the nodes. - node, err := getSchedulable(nodes.Items) - framework.ExpectNoError(err) - ginkgo.By("creating a no-snat-test-proxy Pod on Node " + node.Name + " port " + strconv.Itoa(testProxyPort) + - " so we can target our test Pods through this Node's ExternalIP") - - extIP, err := getIP(v1.NodeExternalIP, node) - framework.ExpectNoError(err) - proxyNodeIP := extIP + ":" + strconv.Itoa(testProxyPort) - - _, err = pc.Create(context.TODO(), newTestProxyPod(node.Name), metav1.CreateOptions{}) - framework.ExpectNoError(err) - ginkgo.By("waiting for all of the no-snat-test pods to be scheduled and running") err = wait.PollImmediate(10*time.Second, 1*time.Minute, func() (bool, error) { - pods, err := pc.List(context.TODO(), metav1.ListOptions{LabelSelector: "no-snat-test"}) + pods, err := pc.List(context.TODO(), metav1.ListOptions{LabelSelector: noSNATTestName}) if err != nil { return false, err } @@ -194,64 +97,22 @@ var _ = SIGDescribe("NoSNAT [Feature:NoSNAT] [Slow]", func() { }) framework.ExpectNoError(err) - ginkgo.By("waiting for the no-snat-test-proxy Pod to be scheduled and running") - err = wait.PollImmediate(10*time.Second, 1*time.Minute, func() (bool, error) { - pod, err := pc.Get(context.TODO(), "no-snat-test-proxy", metav1.GetOptions{}) - if err != nil { - return false, err - } - if pod.Status.Phase != v1.PodRunning { - if pod.Status.Phase != v1.PodPending { - return false, fmt.Errorf("expected pod to be in phase \"Pending\" or \"Running\"") - } - return false, nil // pod is still pending - } - return true, nil // pod is running - }) - framework.ExpectNoError(err) - ginkgo.By("sending traffic from each pod to the others and checking that SNAT does not occur") - pods, err := pc.List(context.TODO(), metav1.ListOptions{LabelSelector: "no-snat-test"}) + pods, err := pc.List(context.TODO(), metav1.ListOptions{LabelSelector: noSNATTestName}) framework.ExpectNoError(err) - // collect pod IPs - podIPs := []string{} - for _, pod := range pods.Items { - podIPs = append(podIPs, pod.Status.PodIP+":"+strconv.Itoa(testPodPort)) - } - - // hit the /checknosnat endpoint on each Pod, tell each Pod to check all the other Pods + // hit the /clientip endpoint on every other Pods to check if source ip is preserved // this test is O(n^2) but it doesn't matter because we only run this test on small clusters (~3 nodes) - errs := []string{} - client := http.Client{ - Timeout: 5 * time.Minute, - } - for _, pip := range podIPs { - ips := []string{} - for _, ip := range podIPs { - if ip == pip { + for _, sourcePod := range pods.Items { + for _, targetPod := range pods.Items { + if targetPod.Name == sourcePod.Name { continue } - ips = append(ips, ip) + targetAddr := net.JoinHostPort(targetPod.Status.PodIP, testPodPort) + sourceIP, execPodIP := execSourceIPTest(sourcePod, targetAddr) + ginkgo.By("Verifying the preserved source ip") + framework.ExpectEqual(sourceIP, execPodIP) } - // hit /checknosnat on pip, via proxy - resp, err := client.Get(checknosnatURL(proxyNodeIP, pip, ips)) - framework.ExpectNoError(err) - - // check error code on the response, if 500 record the body, which will describe the error - if resp.StatusCode == 500 { - body, err := ioutil.ReadAll(resp.Body) - framework.ExpectNoError(err) - errs = append(errs, string(body)) - } - resp.Body.Close() - } - - // report the errors all at the end - if len(errs) > 0 { - str := strings.Join(errs, "\n") - err := fmt.Errorf("/checknosnat failed in the following cases:\n%s", str) - framework.ExpectNoError(err) } }) }) diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/proxy.go b/vendor/k8s.io/kubernetes/test/e2e/network/proxy.go index 8ace511db27f..24dadf0c473b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/proxy.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/proxy.go @@ -78,7 +78,7 @@ var _ = SIGDescribe("Proxy", func() { // using the porter image to serve content, access the content // (of multiple pods?) from multiple (endpoints/services?) /* - Release : v1.9 + Release: v1.9 Testname: Proxy, logs service endpoint Description: Select any node in the cluster to invoke /logs endpoint using the /nodes/proxy subresource from the kubelet port. This endpoint MUST be reachable. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/service.go b/vendor/k8s.io/kubernetes/test/e2e/network/service.go index cce449b5e8ec..35ac43001d22 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/service.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/service.go @@ -17,7 +17,6 @@ limitations under the License. package network import ( - "bytes" "context" "encoding/json" "errors" @@ -34,19 +33,25 @@ import ( compute "google.golang.org/api/compute/v1" + "k8s.io/client-go/tools/cache" + appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" + discoveryv1beta1 "k8s.io/api/discovery/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" + watch "k8s.io/apimachinery/pkg/watch" clientset "k8s.io/client-go/kubernetes" + watchtools "k8s.io/client-go/tools/watch" cloudprovider "k8s.io/cloud-provider" "k8s.io/kubernetes/test/e2e/framework" e2edeployment "k8s.io/kubernetes/test/e2e/framework/deployment" e2eendpoints "k8s.io/kubernetes/test/e2e/framework/endpoints" + e2eendpointslice "k8s.io/kubernetes/test/e2e/framework/endpointslice" e2ekubesystem "k8s.io/kubernetes/test/e2e/framework/kubesystem" e2enetwork "k8s.io/kubernetes/test/e2e/framework/network" e2enode "k8s.io/kubernetes/test/e2e/framework/node" @@ -101,6 +106,9 @@ var ( // portsByPodName is a map that maps pod name to container ports. type portsByPodName map[string][]int +// portsByPodUID is a map that maps pod name to container ports. +type portsByPodUID map[types.UID][]int + // affinityCheckFromPod returns interval, timeout and function pinging the service and // returning pinged hosts for pinging the service from execPod. func affinityCheckFromPod(execPod *v1.Pod, serviceIP string, servicePort int) (time.Duration, time.Duration, func() []string) { @@ -654,6 +662,32 @@ func testHTTPHealthCheckNodePort(ip string, port int, request string) (bool, err return false, fmt.Errorf("unexpected HTTP response code %s from health check responder at %s", resp.Status, url) } +func testHTTPHealthCheckNodePortFromTestContainer(config *e2enetwork.NetworkingTestConfig, host string, port int, timeout time.Duration, expectSucceed bool, threshold int) error { + count := 0 + pollFn := func() (bool, error) { + statusCode, err := config.GetHTTPCodeFromTestContainer( + "/healthz", + host, + port) + if err != nil { + framework.Logf("Got error reading status code from http://%s:%d/healthz via test container: %v", host, port, err) + return false, nil + } + framework.Logf("Got status code from http://%s:%d/healthz via test container: %d", host, port, statusCode) + success := statusCode == 200 + if (success && expectSucceed) || + (!success && !expectSucceed) { + count++ + } + return count >= threshold, nil + } + err := wait.PollImmediate(time.Second, timeout, pollFn) + if err != nil { + return fmt.Errorf("error waiting for healthCheckNodePort: expected at least %d succeed=%v on %v:%v/healthz, got %d", threshold, expectSucceed, host, port, count) + } + return nil +} + // Does an HTTP GET, but does not reuse TCP connections // This masks problems where the iptables rule has changed, but we don't see it func httpGetNoConnectionPoolTimeout(url string, timeout time.Duration) (*http.Response, error) { @@ -722,6 +756,23 @@ func waitForApiserverUp(c clientset.Interface) error { return fmt.Errorf("waiting for apiserver timed out") } +// getEndpointNodesWithInternalIP returns a map of nodenames:internal-ip on which the +// endpoints of the Service are running. +func getEndpointNodesWithInternalIP(jig *e2eservice.TestJig) (map[string]string, error) { + nodesWithIPs, err := jig.GetEndpointNodesWithIP(v1.NodeInternalIP) + if err != nil { + return nil, err + } + endpointsNodeMap := make(map[string]string, len(nodesWithIPs)) + for nodeName, internalIPs := range nodesWithIPs { + if len(internalIPs) < 1 { + return nil, fmt.Errorf("no internal ip found for node %s", nodeName) + } + endpointsNodeMap[nodeName] = internalIPs[0] + } + return endpointsNodeMap, nil +} + var _ = SIGDescribe("Services", func() { f := framework.NewDefaultFramework("services") @@ -747,7 +798,7 @@ var _ = SIGDescribe("Services", func() { // TODO: We get coverage of TCP/UDP and multi-port services through the DNS test. We should have a simpler test for multi-port TCP here. /* - Release : v1.9 + Release: v1.9 Testname: Kubernetes Service Description: By default when a kubernetes cluster is running there MUST be a 'kubernetes' service running in the cluster. */ @@ -757,7 +808,7 @@ var _ = SIGDescribe("Services", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Service, endpoints Description: Create a service with a endpoint without any Pods, the service MUST run and show empty endpoints. Add a pod to the service and the service MUST validate to show all the endpoints for the ports exposed by the Pod. Add another Pod then the list of all Ports exposed by both the Pods MUST be valid and have corresponding service endpoint. Once the second Pod is deleted then set of endpoint MUST be validated to show only ports from the first container that are exposed. Once both pods are deleted the endpoints from the service MUST be empty. */ @@ -810,7 +861,7 @@ var _ = SIGDescribe("Services", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Service, endpoints with multiple ports Description: Create a service with two ports but no Pods are added to the service yet. The service MUST run and show empty set of endpoints. Add a Pod to the first port, service MUST list one endpoint for the Pod on that port. Add another Pod to the second port, service MUST list both the endpoints. Delete the first Pod and the service MUST list only the endpoint to the second Pod. Delete the second Pod and the service must now have empty set of endpoints. */ @@ -973,7 +1024,7 @@ var _ = SIGDescribe("Services", func() { serviceAddress := net.JoinHostPort(serviceIP, strconv.Itoa(servicePort)) for _, pausePod := range pausePods.Items { - sourceIP, execPodIP := execSourceipTest(pausePod, serviceAddress) + sourceIP, execPodIP := execSourceIPTest(pausePod, serviceAddress) ginkgo.By("Verifying the preserved source ip") framework.ExpectEqual(sourceIP, execPodIP) } @@ -1164,7 +1215,7 @@ var _ = SIGDescribe("Services", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Service, NodePort Service Description: Create a TCP NodePort service, and test reachability from a client Pod. The client Pod MUST be able to access the NodePort service by service name and cluster @@ -2747,7 +2798,7 @@ var _ = SIGDescribe("Services", func() { }) /* - Release : v1.18 + Release: v1.18 Testname: Find Kubernetes Service in default Namespace Description: List all Services in all Namespaces, response MUST include a Service named Kubernetes with the Namespace of default. */ @@ -2766,17 +2817,22 @@ var _ = SIGDescribe("Services", func() { framework.ExpectEqual(foundSvc, true, "could not find service 'kubernetes' in service list in all namespaces") }) - ginkgo.It("should test the lifecycle of an Endpoint", func() { - ns := f.Namespace.Name + /* + Release: v1.19 + Testname: Endpoint resource lifecycle + Description: Create an endpoint, the endpoint MUST exist. + The endpoint is updated with a new label, a check after the update MUST find the changes. + The endpoint is then patched with a new IPv4 address and port, a check after the patch MUST the changes. + The endpoint is deleted by it's label, a watch listens for the deleted watch event. + */ + framework.ConformanceIt("should test the lifecycle of an Endpoint", func() { + testNamespaceName := f.Namespace.Name testEndpointName := "testservice" - - ginkgo.By("creating an Endpoint") - _, err := f.ClientSet.CoreV1().Endpoints(ns).Create(context.TODO(), &v1.Endpoints{ + testEndpoints := v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ - Name: testEndpointName, - Namespace: ns, + Name: testEndpointName, Labels: map[string]string{ - "testendpoint-static": "true", + "test-endpoint-static": "true", }, }, Subsets: []v1.EndpointSubset{{ @@ -2789,50 +2845,82 @@ var _ = SIGDescribe("Services", func() { Protocol: v1.ProtocolTCP, }}, }}, - }, metav1.CreateOptions{}) - framework.ExpectNoError(err, "failed to create Endpoint") + } + w := &cache.ListWatch{ + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + options.LabelSelector = "test-endpoint-static=true" + return f.ClientSet.CoreV1().Endpoints(testNamespaceName).Watch(context.TODO(), options) + }, + } + endpointsList, err := f.ClientSet.CoreV1().Endpoints("").List(context.TODO(), metav1.ListOptions{LabelSelector: "test-endpoint-static=true"}) + framework.ExpectNoError(err, "failed to list Endpoints") - // set up a watch for the Endpoint - // this timeout was chosen as there was timeout failure from the CI - endpointWatchTimeoutSeconds := int64(180) - endpointWatch, err := f.ClientSet.CoreV1().Endpoints(ns).Watch(context.TODO(), metav1.ListOptions{LabelSelector: "testendpoint-static=true", TimeoutSeconds: &endpointWatchTimeoutSeconds}) - framework.ExpectNoError(err, "failed to setup watch on newly created Endpoint") - endpointWatchChan := endpointWatch.ResultChan() + ginkgo.By("creating an Endpoint") + _, err = f.ClientSet.CoreV1().Endpoints(testNamespaceName).Create(context.TODO(), &testEndpoints, metav1.CreateOptions{}) + framework.ExpectNoError(err, "failed to create Endpoint") ginkgo.By("waiting for available Endpoint") - for watchEvent := range endpointWatchChan { - if watchEvent.Type == "ADDED" { - break + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = watchtools.Until(ctx, endpointsList.ResourceVersion, w, func(event watch.Event) (bool, error) { + switch event.Type { + case watch.Added: + if endpoints, ok := event.Object.(*v1.Endpoints); ok { + found := endpoints.ObjectMeta.Name == endpoints.Name && + endpoints.Labels["test-endpoint-static"] == "true" + return found, nil + } + default: + framework.Logf("observed event type %v", event.Type) } - } + return false, nil + }) + framework.ExpectNoError(err, "failed to see %v event", watch.Added) ginkgo.By("listing all Endpoints") - endpointsList, err := f.ClientSet.CoreV1().Endpoints("").List(context.TODO(), metav1.ListOptions{LabelSelector: "testendpoint-static=true"}) + endpointsList, err = f.ClientSet.CoreV1().Endpoints("").List(context.TODO(), metav1.ListOptions{LabelSelector: "test-endpoint-static=true"}) framework.ExpectNoError(err, "failed to list Endpoints") - foundEndpointService := false + eventFound := false var foundEndpoint v1.Endpoints for _, endpoint := range endpointsList.Items { - if endpoint.ObjectMeta.Name == testEndpointName && endpoint.ObjectMeta.Namespace == ns { - foundEndpointService = true + if endpoint.ObjectMeta.Name == testEndpointName && endpoint.ObjectMeta.Namespace == testNamespaceName { + eventFound = true foundEndpoint = endpoint break } } - framework.ExpectEqual(foundEndpointService, true, "unable to find Endpoint Service in list of Endpoints") + framework.ExpectEqual(eventFound, true, "unable to find Endpoint Service in list of Endpoints") ginkgo.By("updating the Endpoint") - foundEndpoint.ObjectMeta.Labels["testservice"] = "first-modification" - _, err = f.ClientSet.CoreV1().Endpoints(ns).Update(context.TODO(), &foundEndpoint, metav1.UpdateOptions{}) + foundEndpoint.ObjectMeta.Labels["test-service"] = "updated" + _, err = f.ClientSet.CoreV1().Endpoints(testNamespaceName).Update(context.TODO(), &foundEndpoint, metav1.UpdateOptions{}) framework.ExpectNoError(err, "failed to update Endpoint with new label") + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = watchtools.Until(ctx, endpointsList.ResourceVersion, w, func(event watch.Event) (bool, error) { + switch event.Type { + case watch.Modified: + if endpoints, ok := event.Object.(*v1.Endpoints); ok { + found := endpoints.ObjectMeta.Name == endpoints.Name && + endpoints.Labels["test-endpoint-static"] == "true" + return found, nil + } + default: + framework.Logf("observed event type %v", event.Type) + } + return false, nil + }) + framework.ExpectNoError(err, "failed to see %v event", watch.Modified) + ginkgo.By("fetching the Endpoint") - _, err = f.ClientSet.CoreV1().Endpoints(ns).Get(context.TODO(), testEndpointName, metav1.GetOptions{}) + endpoints, err := f.ClientSet.CoreV1().Endpoints(testNamespaceName).Get(context.TODO(), testEndpointName, metav1.GetOptions{}) framework.ExpectNoError(err, "failed to fetch Endpoint") - framework.ExpectEqual(foundEndpoint.ObjectMeta.Labels["testservice"], "first-modification", "label not patched") + framework.ExpectEqual(foundEndpoint.ObjectMeta.Labels["test-service"], "updated", "failed to update Endpoint %v in namespace %v label not updated", testEndpointName, testNamespaceName) endpointPatch, err := json.Marshal(map[string]interface{}{ "metadata": map[string]interface{}{ "labels": map[string]string{ - "testservice": "second-modification", + "test-service": "patched", }, }, "subsets": []map[string]interface{}{ @@ -2853,14 +2941,30 @@ var _ = SIGDescribe("Services", func() { }) framework.ExpectNoError(err, "failed to marshal JSON for WatchEvent patch") ginkgo.By("patching the Endpoint") - _, err = f.ClientSet.CoreV1().Endpoints(ns).Patch(context.TODO(), testEndpointName, types.StrategicMergePatchType, []byte(endpointPatch), metav1.PatchOptions{}) + _, err = f.ClientSet.CoreV1().Endpoints(testNamespaceName).Patch(context.TODO(), testEndpointName, types.StrategicMergePatchType, []byte(endpointPatch), metav1.PatchOptions{}) framework.ExpectNoError(err, "failed to patch Endpoint") + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = watchtools.Until(ctx, endpoints.ResourceVersion, w, func(event watch.Event) (bool, error) { + switch event.Type { + case watch.Modified: + if endpoints, ok := event.Object.(*v1.Endpoints); ok { + found := endpoints.ObjectMeta.Name == endpoints.Name && + endpoints.Labels["test-endpoint-static"] == "true" + return found, nil + } + default: + framework.Logf("observed event type %v", event.Type) + } + return false, nil + }) + framework.ExpectNoError(err, "failed to see %v event", watch.Modified) ginkgo.By("fetching the Endpoint") - endpoint, err := f.ClientSet.CoreV1().Endpoints(ns).Get(context.TODO(), testEndpointName, metav1.GetOptions{}) + endpoints, err = f.ClientSet.CoreV1().Endpoints(testNamespaceName).Get(context.TODO(), testEndpointName, metav1.GetOptions{}) framework.ExpectNoError(err, "failed to fetch Endpoint") - framework.ExpectEqual(endpoint.ObjectMeta.Labels["testservice"], "second-modification", "failed to patch Endpoint with Label") - endpointSubsetOne := endpoint.Subsets[0] + framework.ExpectEqual(endpoints.ObjectMeta.Labels["test-service"], "patched", "failed to patch Endpoint with Label") + endpointSubsetOne := endpoints.Subsets[0] endpointSubsetOneAddresses := endpointSubsetOne.Addresses[0] endpointSubsetOnePorts := endpointSubsetOne.Ports[0] framework.ExpectEqual(endpointSubsetOneAddresses.IP, "10.0.0.25", "failed to patch Endpoint") @@ -2868,15 +2972,30 @@ var _ = SIGDescribe("Services", func() { framework.ExpectEqual(endpointSubsetOnePorts.Port, int32(8080), "failed to patch Endpoint") ginkgo.By("deleting the Endpoint by Collection") - err = f.ClientSet.CoreV1().Endpoints(ns).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "testendpoint-static=true"}) + err = f.ClientSet.CoreV1().Endpoints(testNamespaceName).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "test-endpoint-static=true"}) framework.ExpectNoError(err, "failed to delete Endpoint by Collection") ginkgo.By("waiting for Endpoint deletion") - for watchEvent := range endpointWatchChan { - if watchEvent.Type == "DELETED" { - break + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = watchtools.Until(ctx, endpoints.ResourceVersion, w, func(event watch.Event) (bool, error) { + switch event.Type { + case watch.Deleted: + if endpoints, ok := event.Object.(*v1.Endpoints); ok { + found := endpoints.ObjectMeta.Name == endpoints.Name && + endpoints.Labels["test-endpoint-static"] == "true" + return found, nil + } + default: + framework.Logf("observed event type %v", event.Type) } - } + return false, nil + }) + framework.ExpectNoError(err, "failed to see %v event", watch.Deleted) + + ginkgo.By("fetching the Endpoint") + _, err = f.ClientSet.CoreV1().Endpoints(testNamespaceName).Get(context.TODO(), testEndpointName, metav1.GetOptions{}) + framework.ExpectError(err, "should not be able to fetch Endpoint") }) }) @@ -2924,11 +3043,18 @@ var _ = SIGDescribe("ESIPP [Slow]", func() { framework.ExpectNoError(err) // Make sure we didn't leak the health check node port. - threshold := 2 - nodes, err := jig.GetEndpointNodes() + const threshold = 2 + nodes, err := getEndpointNodesWithInternalIP(jig) framework.ExpectNoError(err) - for _, ips := range nodes { - err := TestHTTPHealthCheckNodePort(ips[0], healthCheckNodePort, "/healthz", e2eservice.KubeProxyEndpointLagTimeout, false, threshold) + config := e2enetwork.NewNetworkingTestConfig(f, false, false) + for _, internalIP := range nodes { + err := testHTTPHealthCheckNodePortFromTestContainer( + config, + internalIP, + healthCheckNodePort, + e2eservice.KubeProxyLagTimeout, + false, + threshold) framework.ExpectNoError(err) } err = cs.CoreV1().Services(svc.Namespace).Delete(context.TODO(), svc.Name, metav1.DeleteOptions{}) @@ -2962,17 +3088,20 @@ var _ = SIGDescribe("ESIPP [Slow]", func() { }() tcpNodePort := int(svc.Spec.Ports[0].NodePort) - endpointsNodeMap, err := jig.GetEndpointNodes() + + endpointsNodeMap, err := getEndpointNodesWithInternalIP(jig) framework.ExpectNoError(err) - path := "/clientip" - for nodeName, nodeIPs := range endpointsNodeMap { - nodeIP := nodeIPs[0] - ginkgo.By(fmt.Sprintf("reading clientIP using the TCP service's NodePort, on node %v: %v%v%v", nodeName, nodeIP, tcpNodePort, path)) - content := GetHTTPContent(nodeIP, tcpNodePort, e2eservice.KubeProxyLagTimeout, path) - clientIP := content.String() - framework.Logf("ClientIP detected by target pod using NodePort is %s", clientIP) - if strings.HasPrefix(clientIP, "10.") { + dialCmd := "clientip" + config := e2enetwork.NewNetworkingTestConfig(f, false, false) + + for nodeName, nodeIP := range endpointsNodeMap { + ginkgo.By(fmt.Sprintf("reading clientIP using the TCP service's NodePort, on node %v: %v:%v/%v", nodeName, nodeIP, tcpNodePort, dialCmd)) + clientIP, err := GetHTTPContentFromTestContainer(config, nodeIP, tcpNodePort, e2eservice.KubeProxyLagTimeout, dialCmd) + framework.ExpectNoError(err) + framework.Logf("ClientIP detected by target pod using NodePort is %s, the ip of test container is %s", clientIP, config.TestContainerPod.Status.PodIP) + // the clientIP returned by agnhost contains port + if !strings.HasPrefix(clientIP, config.TestContainerPod.Status.PodIP) { framework.Failf("Source IP was NOT preserved") } } @@ -3009,13 +3138,13 @@ var _ = SIGDescribe("ESIPP [Slow]", func() { framework.Failf("Service HealthCheck NodePort was not allocated") } - ips := e2enode.CollectAddresses(nodes, v1.NodeExternalIP) + ips := e2enode.CollectAddresses(nodes, v1.NodeInternalIP) ingressIP := e2eservice.GetIngressPoint(&svc.Status.LoadBalancer.Ingress[0]) svcTCPPort := int(svc.Spec.Ports[0].Port) - threshold := 2 - path := "/healthz" + const threshold = 2 + config := e2enetwork.NewNetworkingTestConfig(f, false, false) for i := 0; i < len(nodes.Items); i++ { endpointNodeName := nodes.Items[i].Name @@ -3034,15 +3163,21 @@ var _ = SIGDescribe("ESIPP [Slow]", func() { // HealthCheck should pass only on the node where num(endpoints) > 0 // All other nodes should fail the healthcheck on the service healthCheckNodePort - for n, publicIP := range ips { + for n, internalIP := range ips { // Make sure the loadbalancer picked up the health check change. // Confirm traffic can reach backend through LB before checking healthcheck nodeport. e2eservice.TestReachableHTTP(ingressIP, svcTCPPort, e2eservice.KubeProxyLagTimeout) expectedSuccess := nodes.Items[n].Name == endpointNodeName port := strconv.Itoa(healthCheckNodePort) - ipPort := net.JoinHostPort(publicIP, port) - framework.Logf("Health checking %s, http://%s%s, expectedSuccess %v", nodes.Items[n].Name, ipPort, path, expectedSuccess) - err := TestHTTPHealthCheckNodePort(publicIP, healthCheckNodePort, path, e2eservice.KubeProxyEndpointLagTimeout, expectedSuccess, threshold) + ipPort := net.JoinHostPort(internalIP, port) + framework.Logf("Health checking %s, http://%s/healthz, expectedSuccess %v", nodes.Items[n].Name, ipPort, expectedSuccess) + err := testHTTPHealthCheckNodePortFromTestContainer( + config, + internalIP, + healthCheckNodePort, + e2eservice.KubeProxyEndpointLagTimeout, + expectedSuccess, + threshold) framework.ExpectNoError(err) } framework.ExpectNoError(e2erc.DeleteRCAndWaitForGC(f.ClientSet, namespace, serviceName)) @@ -3108,8 +3243,7 @@ var _ = SIGDescribe("ESIPP [Slow]", func() { } }) - // TODO: Get rid of [DisabledForLargeClusters] tag when issue #90047 is fixed. - ginkgo.It("should handle updates to ExternalTrafficPolicy field [DisabledForLargeClusters]", func() { + ginkgo.It("should handle updates to ExternalTrafficPolicy field", func() { namespace := f.Namespace.Name serviceName := "external-local-update" jig := e2eservice.NewTestJig(cs, namespace, serviceName) @@ -3142,42 +3276,71 @@ var _ = SIGDescribe("ESIPP [Slow]", func() { framework.Failf("Service HealthCheck NodePort still present") } - endpointNodeMap, err := jig.GetEndpointNodes() + epNodes, err := jig.ListNodesWithEndpoint() framework.ExpectNoError(err) - noEndpointNodeMap := map[string][]string{} + // map from name of nodes with endpoint to internal ip + // it is assumed that there is only a single node with the endpoint + endpointNodeMap := make(map[string]string) + // map from name of nodes without endpoint to internal ip + noEndpointNodeMap := make(map[string]string) + for _, node := range epNodes { + ips := e2enode.GetAddresses(&node, v1.NodeInternalIP) + if len(ips) < 1 { + framework.Failf("No internal ip found for node %s", node.Name) + } + endpointNodeMap[node.Name] = ips[0] + } for _, n := range nodes.Items { - if _, ok := endpointNodeMap[n.Name]; ok { - continue + ips := e2enode.GetAddresses(&n, v1.NodeInternalIP) + if len(ips) < 1 { + framework.Failf("No internal ip found for node %s", n.Name) + } + if _, ok := endpointNodeMap[n.Name]; !ok { + noEndpointNodeMap[n.Name] = ips[0] } - noEndpointNodeMap[n.Name] = e2enode.GetAddresses(&n, v1.NodeExternalIP) } + framework.ExpectNotEqual(len(endpointNodeMap), 0) + framework.ExpectNotEqual(len(noEndpointNodeMap), 0) svcTCPPort := int(svc.Spec.Ports[0].Port) svcNodePort := int(svc.Spec.Ports[0].NodePort) ingressIP := e2eservice.GetIngressPoint(&svc.Status.LoadBalancer.Ingress[0]) path := "/clientip" + dialCmd := "clientip" - ginkgo.By(fmt.Sprintf("endpoints present on nodes %v, absent on nodes %v", endpointNodeMap, noEndpointNodeMap)) - for nodeName, nodeIPs := range noEndpointNodeMap { - ginkgo.By(fmt.Sprintf("Checking %v (%v:%v%v) proxies to endpoints on another node", nodeName, nodeIPs[0], svcNodePort, path)) - GetHTTPContent(nodeIPs[0], svcNodePort, e2eservice.KubeProxyLagTimeout, path) - } + config := e2enetwork.NewNetworkingTestConfig(f, false, false) - for nodeName, nodeIPs := range endpointNodeMap { - ginkgo.By(fmt.Sprintf("checking kube-proxy health check fails on node with endpoint (%s), public IP %s", nodeName, nodeIPs[0])) - var body bytes.Buffer - pollfn := func() (bool, error) { - result := e2enetwork.PokeHTTP(nodeIPs[0], healthCheckNodePort, "/healthz", nil) - if result.Code == 0 { + ginkgo.By(fmt.Sprintf("endpoints present on nodes %v, absent on nodes %v", endpointNodeMap, noEndpointNodeMap)) + for nodeName, nodeIP := range noEndpointNodeMap { + ginkgo.By(fmt.Sprintf("Checking %v (%v:%v/%v) proxies to endpoints on another node", nodeName, nodeIP[0], svcNodePort, dialCmd)) + _, err := GetHTTPContentFromTestContainer(config, nodeIP, svcNodePort, e2eservice.KubeProxyLagTimeout, dialCmd) + framework.ExpectNoError(err, "Could not reach HTTP service through %v:%v/%v after %v", nodeIP, svcNodePort, dialCmd, e2eservice.KubeProxyLagTimeout) + } + + for nodeName, nodeIP := range endpointNodeMap { + ginkgo.By(fmt.Sprintf("checking kube-proxy health check fails on node with endpoint (%s), public IP %s", nodeName, nodeIP)) + var body string + pollFn := func() (bool, error) { + // we expect connection failure here, but not other errors + resp, err := config.GetResponseFromTestContainer( + "http", + "healthz", + nodeIP, + healthCheckNodePort) + if err != nil { + return false, nil + } + if len(resp.Errors) > 0 { return true, nil } - body.Reset() - body.Write(result.Body) + if len(resp.Responses) > 0 { + body = resp.Responses[0] + } return false, nil } - if pollErr := wait.PollImmediate(framework.Poll, e2eservice.TestTimeout, pollfn); pollErr != nil { + if pollErr := wait.PollImmediate(framework.Poll, e2eservice.TestTimeout, pollFn); pollErr != nil { framework.Failf("Kube-proxy still exposing health check on node %v:%v, after ESIPP was turned off. body %s", - nodeName, healthCheckNodePort, body.String()) + nodeName, healthCheckNodePort, body) } } @@ -3224,38 +3387,6 @@ var _ = SIGDescribe("ESIPP [Slow]", func() { }) }) -func execSourceipTest(pausePod v1.Pod, serviceAddress string) (string, string) { - var err error - var stdout string - timeout := 2 * time.Minute - - framework.Logf("Waiting up to %v to get response from %s", timeout, serviceAddress) - cmd := fmt.Sprintf(`curl -q -s --connect-timeout 30 %s/clientip`, serviceAddress) - for start := time.Now(); time.Since(start) < timeout; time.Sleep(2 * time.Second) { - stdout, err = framework.RunHostCmd(pausePod.Namespace, pausePod.Name, cmd) - if err != nil { - framework.Logf("got err: %v, retry until timeout", err) - continue - } - // Need to check output because it might omit in case of error. - if strings.TrimSpace(stdout) == "" { - framework.Logf("got empty stdout, retry until timeout") - continue - } - break - } - - framework.ExpectNoError(err) - - // The stdout return from RunHostCmd is in this format: x.x.x.x:port or [xx:xx:xx::x]:port - host, _, err := net.SplitHostPort(stdout) - if err != nil { - // ginkgo.Fail the test if output format is unexpected. - framework.Failf("exec pod returned unexpected stdout: [%v]\n", stdout) - } - return pausePod.Status.PodIP, host -} - // execAffinityTestForSessionAffinityTimeout is a helper function that wrap the logic of // affinity test for non-load-balancer services. Session afinity will be // enabled when the service is created and a short timeout will be configured so @@ -3570,7 +3701,7 @@ func enableAndDisableInternalLB() (enable func(svc *v1.Service), disable func(sv return framework.TestContext.CloudConfig.Provider.EnableAndDisableInternalLB() } -func validatePorts(ep e2eendpoints.PortsByPodUID, expectedEndpoints e2eendpoints.PortsByPodUID) error { +func validatePorts(ep, expectedEndpoints portsByPodUID) error { if len(ep) != len(expectedEndpoints) { // should not happen because we check this condition before return fmt.Errorf("invalid number of endpoints got %v, expected %v", ep, expectedEndpoints) @@ -3593,8 +3724,8 @@ func validatePorts(ep e2eendpoints.PortsByPodUID, expectedEndpoints e2eendpoints return nil } -func translatePodNameToUID(c clientset.Interface, ns string, expectedEndpoints portsByPodName) (e2eendpoints.PortsByPodUID, error) { - portsByUID := make(e2eendpoints.PortsByPodUID) +func translatePodNameToUID(c clientset.Interface, ns string, expectedEndpoints portsByPodName) (portsByPodUID, error) { + portsByUID := make(portsByPodUID) for name, portList := range expectedEndpoints { pod, err := c.CoreV1().Pods(ns).Get(context.TODO(), name, metav1.GetOptions{}) if err != nil { @@ -3615,21 +3746,42 @@ func validateEndpointsPorts(c clientset.Interface, namespace, serviceName string i := 0 if pollErr := wait.PollImmediate(time.Second, framework.ServiceStartTimeout, func() (bool, error) { + i++ + ep, err := c.CoreV1().Endpoints(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{}) if err != nil { framework.Logf("Failed go get Endpoints object: %v", err) // Retry the error return false, nil } - portsByPodUID := e2eendpoints.GetContainerPortsByPodUID(ep) - - i++ - if err := validatePorts(portsByPodUID, expectedPortsByPodUID); err != nil { + portsByUID := portsByPodUID(e2eendpoints.GetContainerPortsByPodUID(ep)) + if err := validatePorts(portsByUID, expectedPortsByPodUID); err != nil { if i%5 == 0 { - framework.Logf("Unexpected endpoints: found %v, expected %v, will retry", portsByPodUID, expectedEndpoints) + framework.Logf("Unexpected endpoints: found %v, expected %v, will retry", portsByUID, expectedEndpoints) } return false, nil } + + // If EndpointSlice API is enabled, then validate if appropriate EndpointSlice objects + // were also create/updated/deleted. + if _, err := c.Discovery().ServerResourcesForGroupVersion(discoveryv1beta1.SchemeGroupVersion.String()); err == nil { + opts := metav1.ListOptions{ + LabelSelector: "kubernetes.io/service-name=" + serviceName, + } + es, err := c.DiscoveryV1beta1().EndpointSlices(namespace).List(context.TODO(), opts) + if err != nil { + framework.Logf("Failed go list EndpointSlice objects: %v", err) + // Retry the error + return false, nil + } + portsByUID = portsByPodUID(e2eendpointslice.GetContainerPortsByPodUID(es.Items)) + if err := validatePorts(portsByUID, expectedPortsByPodUID); err != nil { + if i%5 == 0 { + framework.Logf("Unexpected endpoint slices: found %v, expected %v, will retry", portsByUID, expectedEndpoints) + } + return false, nil + } + } framework.Logf("successfully validated that service %s in namespace %s exposes endpoints %v", serviceName, namespace, expectedEndpoints) return true, nil diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/service_latency.go b/vendor/k8s.io/kubernetes/test/e2e/network/service_latency.go index 8c14c57c4038..eeb907e16235 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/service_latency.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/service_latency.go @@ -49,7 +49,7 @@ var _ = SIGDescribe("Service endpoints latency", func() { f := framework.NewDefaultFramework("svc-latency") /* - Release : v1.9 + Release: v1.9 Testname: Service endpoint latency, thresholds Description: Run 100 iterations of create service with the Pod running the pause image, measure the time it takes for creating the service and the endpoint with the service name is available. These durations are captured for 100 iterations, then the durations are sorted to compute 50th, 90th and 99th percentile. The single server latency MUST not exceed liberally set thresholds of 20s for 50th percentile and 50s for the 90th percentile. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/network/util.go b/vendor/k8s.io/kubernetes/test/e2e/network/util.go index ec6048c7b1e6..6deaabfbf686 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/network/util.go +++ b/vendor/k8s.io/kubernetes/test/e2e/network/util.go @@ -19,6 +19,7 @@ package network import ( "bytes" "fmt" + "net" "regexp" "strings" "time" @@ -53,6 +54,23 @@ func GetHTTPContent(host string, port int, timeout time.Duration, url string) by return body } +// GetHTTPContentFromTestContainer returns the content of the given url by HTTP via a test container. +func GetHTTPContentFromTestContainer(config *e2enetwork.NetworkingTestConfig, host string, port int, timeout time.Duration, dialCmd string) (string, error) { + var body string + pollFn := func() (bool, error) { + resp, err := config.GetResponseFromTestContainer("http", dialCmd, host, port) + if err != nil || len(resp.Errors) > 0 || len(resp.Responses) == 0 { + return false, nil + } + body = resp.Responses[0] + return true, nil + } + if pollErr := wait.PollImmediate(framework.Poll, timeout, pollFn); pollErr != nil { + return "", pollErr + } + return body, nil +} + // DescribeSvc logs the output of kubectl describe svc for the given namespace func DescribeSvc(ns string) { framework.Logf("\nOutput of kubectl describe svc:\n") @@ -108,3 +126,39 @@ func CheckSCTPModuleLoadedOnNodes(f *framework.Framework, nodes *v1.NodeList) bo } return false } + +// execSourceIPTest executes curl to access "/clientip" endpoint on target address +// from given Pod to check if source ip is preserved. +func execSourceIPTest(sourcePod v1.Pod, targetAddr string) (string, string) { + var ( + err error + stdout string + timeout = 2 * time.Minute + ) + + framework.Logf("Waiting up to %v to get response from %s", timeout, targetAddr) + cmd := fmt.Sprintf(`curl -q -s --connect-timeout 30 %s/clientip`, targetAddr) + for start := time.Now(); time.Since(start) < timeout; time.Sleep(2 * time.Second) { + stdout, err = framework.RunHostCmd(sourcePod.Namespace, sourcePod.Name, cmd) + if err != nil { + framework.Logf("got err: %v, retry until timeout", err) + continue + } + // Need to check output because it might omit in case of error. + if strings.TrimSpace(stdout) == "" { + framework.Logf("got empty stdout, retry until timeout") + continue + } + break + } + + framework.ExpectNoError(err) + + // The stdout return from RunHostCmd is in this format: x.x.x.x:port or [xx:xx:xx::x]:port + host, _, err := net.SplitHostPort(stdout) + if err != nil { + // ginkgo.Fail the test if output format is unexpected. + framework.Failf("exec pod returned unexpected stdout: [%v]\n", stdout) + } + return sourcePod.Status.PodIP, host +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/node/events.go b/vendor/k8s.io/kubernetes/test/e2e/node/events.go index e25918101fdc..c7cd14af6fb1 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/node/events.go +++ b/vendor/k8s.io/kubernetes/test/e2e/node/events.go @@ -37,7 +37,7 @@ var _ = SIGDescribe("Events", func() { f := framework.NewDefaultFramework("events") /* - Release : v1.9 + Release: v1.9 Testname: Pod events, verify event from Scheduler and Kubelet Description: Create a Pod, make sure that the Pod can be queried. Create a event selector for the kind=Pod and the source is the Scheduler. List of the events MUST be at least one. Create a event selector for kind=Pod and the source is the Kubelet. List of the events MUST be at least one. Both Scheduler and Kubelet MUST send events when scheduling and running a Pod. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/node/pod_hostnamefqdn.go b/vendor/k8s.io/kubernetes/test/e2e/node/pod_hostnamefqdn.go index b06636cfa684..bb9d6140766f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/node/pod_hostnamefqdn.go +++ b/vendor/k8s.io/kubernetes/test/e2e/node/pod_hostnamefqdn.go @@ -67,7 +67,7 @@ var _ = SIGDescribe("Hostname of Pod [Feature:SetHostnameAsFQDN]", func() { f := framework.NewDefaultFramework("hostfqdn") /* - Release : v1.19 + Release: v1.19 Testname: Create Pod without fully qualified domain name (FQDN) Description: A Pod that does not define the subdomain field in it spec, does not have FQDN. */ @@ -80,7 +80,7 @@ var _ = SIGDescribe("Hostname of Pod [Feature:SetHostnameAsFQDN]", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: Create Pod without FQDN, setHostnameAsFQDN field set to true Description: A Pod that does not define the subdomain field in it spec, does not have FQDN. Hence, SetHostnameAsFQDN feature has no effect. @@ -97,7 +97,7 @@ var _ = SIGDescribe("Hostname of Pod [Feature:SetHostnameAsFQDN]", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: Create Pod with FQDN, setHostnameAsFQDN field not defined. Description: A Pod that defines the subdomain field in it spec has FQDN. hostname command returns shortname (pod name in this case), and hostname -f returns FQDN. @@ -116,7 +116,7 @@ var _ = SIGDescribe("Hostname of Pod [Feature:SetHostnameAsFQDN]", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: Create Pod with FQDN, setHostnameAsFQDN field set to true. Description: A Pod that defines the subdomain field in it spec has FQDN. When setHostnameAsFQDN: true, the hostname is set to be the FQDN. In this case, both commands hostname and hostname -f return the FQDN of the Pod. diff --git a/vendor/k8s.io/kubernetes/test/e2e/node/pods.go b/vendor/k8s.io/kubernetes/test/e2e/node/pods.go index f6a472d28cdd..f863f7c4bf11 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/node/pods.go +++ b/vendor/k8s.io/kubernetes/test/e2e/node/pods.go @@ -53,7 +53,7 @@ var _ = SIGDescribe("Pods Extended", func() { }) /* - Release : v1.15 + Release: v1.15 Testname: Pods, delete grace period Description: Create a pod, make sure it is running. Using the http client send a 'delete' with gracePeriodSeconds=30. Pod SHOULD get terminated within gracePeriodSeconds and removed from API server within a window. */ @@ -163,7 +163,7 @@ var _ = SIGDescribe("Pods Extended", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pods, QOS Description: Create a Pod with CPU and Memory request and limits. Pod status MUST have QOSClass set to PodQOSGuaranteed. Behaviors: diff --git a/vendor/k8s.io/kubernetes/test/e2e/node/pre_stop.go b/vendor/k8s.io/kubernetes/test/e2e/node/pre_stop.go index 73388489349d..a1391621d5eb 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/node/pre_stop.go +++ b/vendor/k8s.io/kubernetes/test/e2e/node/pre_stop.go @@ -173,7 +173,7 @@ var _ = SIGDescribe("PreStop", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Pods, prestop hook Description: Create a server pod with a rest endpoint '/write' that changes state.Received field. Create a Pod with a pre-stop handle that posts to the /write endpoint on the server Pod. Verify that the Pod with pre-stop hook is running. Delete the Pod with the pre-stop hook. Before the Pod is deleted, pre-stop handler MUST be called when configured. Verify that the Pod is deleted and a call to prestop hook is verified by checking the status received on the server Pod. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/node/taints.go b/vendor/k8s.io/kubernetes/test/e2e/node/taints.go index e1af97532931..d3c395316f2d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/node/taints.go +++ b/vendor/k8s.io/kubernetes/test/e2e/node/taints.go @@ -282,7 +282,7 @@ var _ = SIGDescribe("NoExecuteTaintManager Single Pod [Serial]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Taint, Pod Eviction on taint removal Description: The Pod with toleration timeout scheduled on a tainted Node MUST not be evicted if the taint is removed before toleration time ends. @@ -412,7 +412,7 @@ var _ = SIGDescribe("NoExecuteTaintManager Multiple Pods [Serial]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Pod Eviction, Toleration limits Description: In a multi-pods scenario with tolerationSeconds, the pods MUST be evicted as per the toleration time limit. diff --git a/vendor/k8s.io/kubernetes/test/e2e/scheduling/limit_range.go b/vendor/k8s.io/kubernetes/test/e2e/scheduling/limit_range.go index 92d334393e25..6beeb5565ec7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/scheduling/limit_range.go +++ b/vendor/k8s.io/kubernetes/test/e2e/scheduling/limit_range.go @@ -38,7 +38,6 @@ import ( imageutils "k8s.io/kubernetes/test/utils/image" "github.com/onsi/ginkgo" - "github.com/onsi/gomega" ) const ( @@ -49,7 +48,7 @@ var _ = SIGDescribe("LimitRange", func() { f := framework.NewDefaultFramework("limitrange") /* - Release : v1.18 + Release: v1.18 Testname: LimitRange, resources Description: Creating a Limitrange and verifying the creation of Limitrange, updating the Limitrange and validating the Limitrange. Creating Pods with resources and validate the pod resources are applied to the Limitrange */ @@ -206,10 +205,8 @@ var _ = SIGDescribe("LimitRange", func() { framework.ExpectNoError(err) ginkgo.By("Verifying the LimitRange was deleted") - gomega.Expect(wait.Poll(time.Second*5, e2eservice.RespondingTimeout, func() (bool, error) { - selector := labels.SelectorFromSet(labels.Set(map[string]string{"name": limitRange.Name})) - options := metav1.ListOptions{LabelSelector: selector.String()} - limitRanges, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).List(context.TODO(), options) + err = wait.Poll(time.Second*5, e2eservice.RespondingTimeout, func() (bool, error) { + limitRanges, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{}) if err != nil { framework.Logf("Unable to retrieve LimitRanges: %v", err) @@ -221,19 +218,14 @@ var _ = SIGDescribe("LimitRange", func() { return true, nil } - if len(limitRanges.Items) > 0 { - if limitRanges.Items[0].ObjectMeta.DeletionTimestamp == nil { - framework.Logf("deletion has not yet been observed") - return false, nil - } - return true, nil + for i := range limitRanges.Items { + lr := limitRanges.Items[i] + framework.Logf("LimitRange %v/%v has not yet been deleted", lr.Namespace, lr.Name) } return false, nil - - })) - - framework.ExpectNoError(err, "kubelet never observed the termination notice") + }) + framework.ExpectNoError(err) ginkgo.By("Creating a Pod with more than former max resources") pod = newTestPod(podName+"2", getResourceList("600m", "600Mi", "600Gi"), v1.ResourceList{}) diff --git a/vendor/k8s.io/kubernetes/test/e2e/scheduling/predicates.go b/vendor/k8s.io/kubernetes/test/e2e/scheduling/predicates.go index ff74c8cf02cd..61e4687ae54c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/scheduling/predicates.go +++ b/vendor/k8s.io/kubernetes/test/e2e/scheduling/predicates.go @@ -315,7 +315,7 @@ var _ = SIGDescribe("SchedulerPredicates [Serial]", func() { // 4. Create another pod with no affinity to any node that need 50% of the largest node CPU. // 5. Make sure this additional pod is not scheduled. /* - Release : v1.9 + Release: v1.9 Testname: Scheduler, resource limits Description: Scheduling Pods MUST fail if the resource requests exceed Machine capacity. */ @@ -425,7 +425,7 @@ var _ = SIGDescribe("SchedulerPredicates [Serial]", func() { // Test Nodes does not have any label, hence it should be impossible to schedule Pod with // nonempty Selector set. /* - Release : v1.9 + Release: v1.9 Testname: Scheduler, node selector not matching Description: Create a Pod with a NodeSelector set to a value that does not match a node in the cluster. Since there are no nodes matching the criteria the Pod MUST not be scheduled. */ @@ -448,7 +448,7 @@ var _ = SIGDescribe("SchedulerPredicates [Serial]", func() { }) /* - Release : v1.9 + Release: v1.9 Testname: Scheduler, node selector matching Description: Create a label on the node {k: v}. Then create a Pod with a NodeSelector set to {k: v}. Check to see if the Pod is scheduled. When the NodeSelector matches then Pod MUST be scheduled on that node. */ @@ -652,7 +652,7 @@ var _ = SIGDescribe("SchedulerPredicates [Serial]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Scheduling, HostPort matching and HostIP and Protocol not-matching Description: Pods with the same HostPort value MUST be able to be scheduled to the same node if the HostIP or Protocol is different. @@ -685,7 +685,7 @@ var _ = SIGDescribe("SchedulerPredicates [Serial]", func() { }) /* - Release : v1.16 + Release: v1.16 Testname: Scheduling, HostPort and Protocol match, HostIPs different but one is default HostIP (0.0.0.0) Description: Pods with the same HostPort and Protocol, but different HostIPs, MUST NOT schedule to the same node if one of those IPs is the default HostIP of 0.0.0.0, which represents all IPs on the host. diff --git a/vendor/k8s.io/kubernetes/test/e2e/scheduling/preemption.go b/vendor/k8s.io/kubernetes/test/e2e/scheduling/preemption.go index b4252bca135b..03481a7d69ad 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/scheduling/preemption.go +++ b/vendor/k8s.io/kubernetes/test/e2e/scheduling/preemption.go @@ -111,7 +111,7 @@ var _ = SIGDescribe("SchedulerPreemption [Serial]", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: Scheduler, Basic Preemption Description: When a higher priority pod is created and no node with enough resources is found, the scheduler MUST preempt a lower priority pod and @@ -199,7 +199,7 @@ var _ = SIGDescribe("SchedulerPreemption [Serial]", func() { }) /* - Release : v1.19 + Release: v1.19 Testname: Scheduler, Preemption for critical pod Description: When a critical pod is created and no node with enough resources is found, the scheduler MUST preempt a lower priority pod to diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/BUILD b/vendor/k8s.io/kubernetes/test/e2e/storage/BUILD index 56e4bd1f96b2..a4361e764ac7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/BUILD @@ -66,6 +66,8 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", + "//staging/src/k8s.io/client-go/tools/cache:go_default_library", + "//staging/src/k8s.io/client-go/tools/watch:go_default_library", "//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library", "//staging/src/k8s.io/component-base/metrics/testutil:go_default_library", "//test/e2e/framework:go_default_library", diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/csi_mock_volume.go b/vendor/k8s.io/kubernetes/test/e2e/storage/csi_mock_volume.go index 74fad8c24e01..147e02d23fd4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/csi_mock_volume.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/csi_mock_volume.go @@ -39,6 +39,8 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" clientset "k8s.io/client-go/kubernetes" + cachetools "k8s.io/client-go/tools/cache" + watchtools "k8s.io/client-go/tools/watch" "k8s.io/kubernetes/pkg/controller/volume/scheduling" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" @@ -151,11 +153,16 @@ var _ = utils.SIGDescribe("CSI mock volume", func() { if tp.registerDriver { err = waitForCSIDriver(cs, m.config.GetUniqueDriverName()) - framework.ExpectNoError(err, "Failed to get CSIDriver : %v", err) + framework.ExpectNoError(err, "Failed to get CSIDriver %v", m.config.GetUniqueDriverName()) m.testCleanups = append(m.testCleanups, func() { destroyCSIDriver(cs, m.config.GetUniqueDriverName()) }) } + + // Wait for the CSIDriver actually get deployed and CSINode object to be generated. + // This indicates the mock CSI driver pod is up and running healthy. + err = drivers.WaitForCSIDriverRegistrationOnNode(m.config.ClientNodeSelection.Name, m.config.GetUniqueDriverName(), cs) + framework.ExpectNoError(err, "Failed to register CSIDriver %v", m.config.GetUniqueDriverName()) } createPod := func(ephemeral bool) (class *storagev1.StorageClass, claim *v1.PersistentVolumeClaim, pod *v1.Pod) { @@ -821,7 +828,20 @@ var _ = utils.SIGDescribe("CSI mock volume", func() { ctx, cancel := context.WithTimeout(context.Background(), csiPodRunningTimeout) defer cancel() - pvcWatch, err := f.ClientSet.CoreV1().PersistentVolumeClaims(f.Namespace.Name).Watch(ctx, metav1.ListOptions{}) + + // In contrast to the raw watch, RetryWatcher is expected to deliver all events even + // when the underlying raw watch gets closed prematurely + // (https://github.com/kubernetes/kubernetes/pull/93777#discussion_r467932080). + // This is important because below the test is going to make assertions about the + // PVC state changes. + initResource, err := f.ClientSet.CoreV1().PersistentVolumeClaims(f.Namespace.Name).List(ctx, metav1.ListOptions{}) + framework.ExpectNoError(err, "Failed to fetch initial PVC resource") + listWatcher := &cachetools.ListWatch{ + WatchFunc: func(listOptions metav1.ListOptions) (watch.Interface, error) { + return f.ClientSet.CoreV1().PersistentVolumeClaims(f.Namespace.Name).Watch(ctx, listOptions) + }, + } + pvcWatch, err := watchtools.NewRetryWatcher(initResource.GetResourceVersion(), listWatcher) framework.ExpectNoError(err, "create PVC watch") defer pvcWatch.Stop() @@ -889,12 +909,14 @@ var _ = utils.SIGDescribe("CSI mock volume", func() { ginkgo.By("Checking PVC events") nodeAnnotationSet := false nodeAnnotationReset := false + watchFailed := false loop: for { select { case event, ok := <-pvcWatch.ResultChan(): if !ok { - framework.Failf("PVC watch ended prematurely") + watchFailed = true + break loop } framework.Logf("PVC event %s: %#v", event.Type, event.Object) @@ -913,10 +935,8 @@ var _ = utils.SIGDescribe("CSI mock volume", func() { case watch.Deleted: break loop case watch.Error: - // Can this occur when the apiserver is under heavy load? - // If yes, then we should bail out of the test here early and - // skip further checks instead of treating it as a test failure. - framework.Failf("PVC watch failed prematurely: %v", event.Object) + watchFailed = true + break } case <-ctx.Done(): framework.Failf("Timeout while waiting to observe PVC list") @@ -932,7 +952,13 @@ var _ = utils.SIGDescribe("CSI mock volume", func() { } } - if test.lateBinding { + switch { + case watchFailed: + // If the watch failed or stopped prematurely (which can happen at any time), then we cannot + // verify whether the annotation was set as expected. This is still considered a successful + // test. + framework.Logf("PVC watch delivered incomplete data, cannot check annotation") + case test.lateBinding: gomega.Expect(nodeAnnotationSet).To(gomega.BeTrue(), "selected-node should have been set") // Whether it gets reset depends on whether we have topology enabled. Without // it, rescheduling is unnecessary. @@ -941,7 +967,7 @@ var _ = utils.SIGDescribe("CSI mock volume", func() { } else { gomega.Expect(nodeAnnotationReset).To(gomega.BeFalse(), "selected-node should not have been reset") } - } else { + default: gomega.Expect(nodeAnnotationSet).To(gomega.BeFalse(), "selected-node should not have been set") gomega.Expect(nodeAnnotationReset).To(gomega.BeFalse(), "selected-node should not have been reset") } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi.go b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi.go index 88b9ef7a888b..6783e6bf31d7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi.go @@ -608,17 +608,25 @@ func waitForCSIDriverRegistrationOnAllNodes(driverName string, cs clientset.Inte return err } for _, node := range nodes.Items { - if err := waitForCSIDriverRegistrationOnNode(node.Name, driverName, cs); err != nil { + if err := WaitForCSIDriverRegistrationOnNode(node.Name, driverName, cs); err != nil { return err } } return nil } -func waitForCSIDriverRegistrationOnNode(nodeName string, driverName string, cs clientset.Interface) error { - const csiNodeRegisterTimeout = 5 * time.Minute +// WaitForCSIDriverRegistrationOnNode waits for the CSINode object generated by the node-registrar on a certain node +func WaitForCSIDriverRegistrationOnNode(nodeName string, driverName string, cs clientset.Interface) error { + framework.Logf("waiting for CSIDriver %v to register on node %v", driverName, nodeName) - waitErr := wait.PollImmediate(10*time.Second, csiNodeRegisterTimeout, func() (bool, error) { + // About 8.6 minutes timeout + backoff := wait.Backoff{ + Duration: 2 * time.Second, + Factor: 1.5, + Steps: 12, + } + + waitErr := wait.ExponentialBackoff(backoff, func() (bool, error) { csiNode, err := cs.StorageV1().CSINodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) if err != nil && !apierrors.IsNotFound(err) { return false, err diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/in_tree.go b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/in_tree.go index d5183f280814..a866266c1f1e 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/in_tree.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/in_tree.go @@ -324,14 +324,26 @@ func (v *glusterVolume) DeleteVolume() { name := v.prefix + "-server" - framework.Logf("Deleting Gluster endpoints %q...", name) + nameSpaceName := fmt.Sprintf("%s/%s", ns.Name, name) + + framework.Logf("Deleting Gluster endpoints %s...", nameSpaceName) err := cs.CoreV1().Endpoints(ns.Name).Delete(context.TODO(), name, metav1.DeleteOptions{}) if err != nil { if !apierrors.IsNotFound(err) { - framework.Failf("Gluster delete endpoints failed: %v", err) + framework.Failf("Gluster deleting endpoint %s failed: %v", nameSpaceName, err) } - framework.Logf("Gluster endpoints %q not found, assuming deleted", name) + framework.Logf("Gluster endpoints %q not found, assuming deleted", nameSpaceName) } + + framework.Logf("Deleting Gluster service %s...", nameSpaceName) + err = cs.CoreV1().Services(ns.Name).Delete(context.TODO(), name, metav1.DeleteOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + framework.Failf("Gluster deleting service %s failed: %v", nameSpaceName, err) + } + framework.Logf("Gluster service %q not found, assuming deleted", nameSpaceName) + } + framework.Logf("Deleting Gluster server pod %q...", v.serverPod.Name) err = e2epod.DeletePodWithWait(cs, v.serverPod) if err != nil { diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/empty_dir_wrapper.go b/vendor/k8s.io/kubernetes/test/e2e/storage/empty_dir_wrapper.go index 48718dfd0923..a9054369fe89 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/empty_dir_wrapper.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/empty_dir_wrapper.go @@ -58,7 +58,7 @@ var _ = utils.SIGDescribe("EmptyDir wrapper volumes", func() { f := framework.NewDefaultFramework("emptydir-wrapper") /* - Release : v1.13 + Release: v1.13 Testname: EmptyDir Wrapper Volume, Secret and ConfigMap volumes, no conflict Description: Secret volume and ConfigMap volume is created with data. Pod MUST be able to start with Secret and ConfigMap volumes mounted into the container. */ @@ -180,7 +180,7 @@ var _ = utils.SIGDescribe("EmptyDir wrapper volumes", func() { // appears to be less prone to the race problem. /* - Release : v1.13 + Release: v1.13 Testname: EmptyDir Wrapper Volume, ConfigMap volumes, no race Description: Create 50 ConfigMaps Volumes and 5 replicas of pod with these ConfigMapvolumes mounted. Pod MUST NOT fail waiting for Volumes. */ diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/pd.go b/vendor/k8s.io/kubernetes/test/e2e/storage/pd.go index b6d720406aa7..f5b6060a834b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/pd.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/pd.go @@ -451,6 +451,37 @@ var _ = utils.SIGDescribe("Pod Disks", func() { ginkgo.By("delete a PD") framework.ExpectNoError(e2epv.DeletePDWithRetry("non-exist")) }) + + // This test is marked to run as serial so as device selection on AWS does not + // conflict with other concurrent attach operations. + ginkgo.It("[Serial] attach on previously attached volumes should work", func() { + e2eskipper.SkipUnlessProviderIs("gce", "gke", "aws") + ginkgo.By("creating PD") + diskName, err := e2epv.CreatePDWithRetry() + framework.ExpectNoError(err, "Error creating PD") + + // this should be safe to do because if attach fails then detach will be considered + // successful and we will delete the volume. + defer func() { + detachAndDeletePDs(diskName, []types.NodeName{host0Name}) + }() + + ginkgo.By("Attaching volume to a node") + err = attachPD(host0Name, diskName) + framework.ExpectNoError(err, "Error attaching PD") + + pod := testPDPod([]string{diskName}, host0Name /*readOnly*/, false, 1) + ginkgo.By("Creating test pod with same volume") + _, err = podClient.Create(context.TODO(), pod, metav1.CreateOptions{}) + framework.ExpectNoError(err, "Failed to create pod") + framework.ExpectNoError(e2epod.WaitForPodRunningInNamespaceSlow(f.ClientSet, pod.Name, f.Namespace.Name)) + + ginkgo.By("deleting the pod") + framework.ExpectNoError(podClient.Delete(context.TODO(), pod.Name, *metav1.NewDeleteOptions(0)), "Failed to delete pod") + framework.Logf("deleted pod %q", pod.Name) + ginkgo.By("waiting for PD to detach") + framework.ExpectNoError(waitForPDDetach(diskName, host0Name)) + }) }) func countReadyNodes(c clientset.Interface, hostName types.NodeName) int { @@ -474,6 +505,7 @@ func verifyPDContentsViaContainer(namespace string, f *framework.Framework, podN } } +// TODO: move detachPD to standard cloudprovider functions so as these tests can run on other cloudproviders too func detachPD(nodeName types.NodeName, pdName string) error { if framework.TestContext.Provider == "gce" || framework.TestContext.Provider == "gke" { gceCloud, err := gce.GetGCECloud() @@ -512,6 +544,38 @@ func detachPD(nodeName types.NodeName, pdName string) error { } } +// TODO: move attachPD to standard cloudprovider functions so as these tests can run on other cloudproviders too +func attachPD(nodeName types.NodeName, pdName string) error { + if framework.TestContext.Provider == "gce" || framework.TestContext.Provider == "gke" { + gceCloud, err := gce.GetGCECloud() + if err != nil { + return err + } + err = gceCloud.AttachDisk(pdName, nodeName, false /*readOnly*/, false /*regional*/) + if err != nil { + framework.Logf("Error attaching PD %q: %v", pdName, err) + } + return err + + } else if framework.TestContext.Provider == "aws" { + awsSession, err := session.NewSession() + if err != nil { + return fmt.Errorf("error creating session: %v", err) + } + client := ec2.New(awsSession) + tokens := strings.Split(pdName, "/") + awsVolumeID := tokens[len(tokens)-1] + ebsUtil := utils.NewEBSUtil(client) + err = ebsUtil.AttachDisk(awsVolumeID, string(nodeName)) + if err != nil { + return fmt.Errorf("error attaching volume %s to node %s: %v", awsVolumeID, nodeName, err) + } + return nil + } else { + return fmt.Errorf("Provider does not support volume attaching") + } +} + // Returns pod spec suitable for api Create call. Handles gce, gke and aws providers only and // escapes if a different provider is supplied. // The first container name is hard-coded to "mycontainer". Subsequent containers are named: diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/subpath.go b/vendor/k8s.io/kubernetes/test/e2e/storage/subpath.go index c8798b672a29..5211c74a11de 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/subpath.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/subpath.go @@ -51,7 +51,7 @@ var _ = utils.SIGDescribe("Subpath", func() { }) /* - Release : v1.12 + Release: v1.12 Testname: SubPath: Reading content from a secret volume. Description: Containers in a pod can read content from a secret mounted volume which was configured with a subpath. This test is marked LinuxOnly since Windows cannot mount individual files in Containers. @@ -63,7 +63,7 @@ var _ = utils.SIGDescribe("Subpath", func() { }) /* - Release : v1.12 + Release: v1.12 Testname: SubPath: Reading content from a configmap volume. Description: Containers in a pod can read content from a configmap mounted volume which was configured with a subpath. This test is marked LinuxOnly since Windows cannot mount individual files in Containers. @@ -75,7 +75,7 @@ var _ = utils.SIGDescribe("Subpath", func() { }) /* - Release : v1.12 + Release: v1.12 Testname: SubPath: Reading content from a configmap volume. Description: Containers in a pod can read content from a configmap mounted volume which was configured with a subpath and also using a mountpath that is a specific file. This test is marked LinuxOnly since Windows cannot mount individual files in Containers. @@ -89,7 +89,7 @@ var _ = utils.SIGDescribe("Subpath", func() { }) /* - Release : v1.12 + Release: v1.12 Testname: SubPath: Reading content from a downwardAPI volume. Description: Containers in a pod can read content from a downwardAPI mounted volume which was configured with a subpath. This test is marked LinuxOnly since Windows cannot mount individual files in Containers. @@ -105,7 +105,7 @@ var _ = utils.SIGDescribe("Subpath", func() { }) /* - Release : v1.12 + Release: v1.12 Testname: SubPath: Reading content from a projected volume. Description: Containers in a pod can read content from a projected mounted volume which was configured with a subpath. This test is marked LinuxOnly since Windows cannot mount individual files in Containers. diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/testpatterns/testpattern.go b/vendor/k8s.io/kubernetes/test/e2e/storage/testpatterns/testpattern.go index ed71723b88c4..37d872d8b08a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/testpatterns/testpattern.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/testpatterns/testpattern.go @@ -248,12 +248,13 @@ var ( FsType: "ntfs", FeatureTag: "[sig-windows]", } - // NtfsDynamicPV is TestPattern for "Dynamic PV (xfs)" + // NtfsDynamicPV is TestPattern for "Dynamic PV (ntfs)" NtfsDynamicPV = TestPattern{ - Name: "Dynamic PV (ntfs)", - VolType: DynamicPV, - FsType: "ntfs", - FeatureTag: "[sig-windows]", + Name: "Dynamic PV (ntfs)", + VolType: DynamicPV, + FsType: "ntfs", + FeatureTag: "[sig-windows]", + SnapshotDeletionPolicy: DeleteSnapshot, } // Definitions for Filesystem volume mode diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/ephemeral.go b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/ephemeral.go index 47314ab8d951..45b7abe81254 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/ephemeral.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/ephemeral.go @@ -207,7 +207,7 @@ func (p *ephemeralTestSuite) DefineTests(driver TestDriver, pattern testpatterns storageutils.VerifyExecInPodSucceed(f, pod2, "[ ! -f /mnt/test-0/hello-world ]") } - defer StopPod(f.ClientSet, pod2) + defer StopPodAndDependents(f.ClientSet, pod2) return nil } @@ -302,7 +302,7 @@ func (t EphemeralTest) TestEphemeral() { pod := StartInPodWithInlineVolume(client, t.Namespace, "inline-volume-tester", command, volumes, t.ReadOnly, t.Node) defer func() { // pod might be nil now. - StopPod(client, pod) + StopPodAndDependents(client, pod) }() framework.ExpectNoError(e2epod.WaitForPodRunningInNamespaceSlow(client, pod.Name, pod.Namespace), "waiting for pod with inline volume") runningPod, err := client.CoreV1().Pods(pod.Namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{}) @@ -315,7 +315,7 @@ func (t EphemeralTest) TestEphemeral() { runningPodData = t.RunningPodCheck(pod) } - StopPod(client, pod) + StopPodAndDependents(client, pod) pod = nil // Don't stop twice. // There should be no dangling PVCs in the namespace now. There might be for @@ -446,7 +446,7 @@ func VolumeSourceEnabled(c clientset.Interface, ns string, volume v1.VolumeSourc switch { case err == nil: // Pod was created, feature supported. - StopPod(c, pod) + StopPodAndDependents(c, pod) return true, nil case apierrors.IsInvalid(err): // "Invalid" because it uses a feature that isn't supported. diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/provisioning.go b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/provisioning.go index de2aaf9ec10c..5554a1ce4c81 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/provisioning.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/provisioning.go @@ -712,6 +712,38 @@ func StopPod(c clientset.Interface, pod *v1.Pod) { e2epod.DeletePodWithWait(c, pod) } +// StopPodAndDependents first tries to log the output of the pod's container, +// then deletes the pod and waits for that to succeed. Also waits for all owned +// resources to be deleted. +func StopPodAndDependents(c clientset.Interface, pod *v1.Pod) { + if pod == nil { + return + } + body, err := c.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &v1.PodLogOptions{}).Do(context.TODO()).Raw() + if err != nil { + framework.Logf("Error getting logs for pod %s: %v", pod.Name, err) + } else { + framework.Logf("Pod %s has the following logs: %s", pod.Name, body) + } + framework.Logf("Deleting pod %q in namespace %q", pod.Name, pod.Namespace) + deletionPolicy := metav1.DeletePropagationForeground + err = c.CoreV1().Pods(pod.Namespace).Delete(context.TODO(), pod.Name, + metav1.DeleteOptions{ + // If the pod is the owner of some resources (like ephemeral inline volumes), + // then we want to be sure that those are also gone before we return. + // Blocking pod deletion via metav1.DeletePropagationForeground achieves that. + PropagationPolicy: &deletionPolicy, + }) + if err != nil { + if apierrors.IsNotFound(err) { + return // assume pod was already deleted + } + framework.Logf("pod Delete API error: %v", err) + } + framework.Logf("Wait up to %v for pod %q to be fully deleted", e2epod.PodDeleteTimeout, pod.Name) + e2epod.WaitForPodNotFoundInNamespace(c, pod.Name, pod.Namespace, e2epod.PodDeleteTimeout) +} + func verifyPVCsPending(client clientset.Interface, pvcs []*v1.PersistentVolumeClaim) { for _, claim := range pvcs { // Get new copy of the claim diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/snapshottable.go b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/snapshottable.go index 7cba54f7b6b8..b1065db0da18 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/snapshottable.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/snapshottable.go @@ -330,7 +330,7 @@ func DeleteAndWaitSnapshot(dc dynamic.Interface, ns string, snapshotName string, var err error ginkgo.By("deleting the snapshot") err = dc.Resource(SnapshotGVR).Namespace(ns).Delete(context.TODO(), snapshotName, metav1.DeleteOptions{}) - if err != nil { + if err != nil && !apierrors.IsNotFound(err) { return err } @@ -441,12 +441,18 @@ func (sr *SnapshotResource) CleanupResource() error { framework.ExpectNoError(err) } err = dc.Resource(SnapshotGVR).Namespace(sr.Vs.GetNamespace()).Delete(context.TODO(), sr.Vs.GetName(), metav1.DeleteOptions{}) + if apierrors.IsNotFound(err) { + err = nil + } framework.ExpectNoError(err) err = utils.WaitForGVRDeletion(dc, SnapshotContentGVR, boundVsContent.GetName(), framework.Poll, framework.SnapshotDeleteTimeout) framework.ExpectNoError(err) case apierrors.IsNotFound(err): // the volume snapshot is not bound to snapshot content yet err = dc.Resource(SnapshotGVR).Namespace(sr.Vs.GetNamespace()).Delete(context.TODO(), sr.Vs.GetName(), metav1.DeleteOptions{}) + if apierrors.IsNotFound(err) { + err = nil + } framework.ExpectNoError(err) err = utils.WaitForGVRDeletion(dc, SnapshotGVR, sr.Vs.GetName(), framework.Poll, framework.SnapshotDeleteTimeout) framework.ExpectNoError(err) @@ -474,6 +480,9 @@ func (sr *SnapshotResource) CleanupResource() error { framework.ExpectNoError(err) } err = dc.Resource(SnapshotContentGVR).Namespace(sr.Vscontent.GetNamespace()).Delete(context.TODO(), sr.Vscontent.GetName(), metav1.DeleteOptions{}) + if apierrors.IsNotFound(err) { + err = nil + } framework.ExpectNoError(err) err = utils.WaitForGVRDeletion(dc, SnapshotContentGVR, sr.Vscontent.GetName(), framework.Poll, framework.SnapshotDeleteTimeout) diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/subpath.go b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/subpath.go index 29adc9f7d3ee..4f493bc0ad08 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/subpath.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/subpath.go @@ -1059,6 +1059,9 @@ func formatVolume(f *framework.Framework, pod *v1.Pod) { } func podContainerExec(pod *v1.Pod, containerIndex int, command string) (string, error) { + if containerIndex > len(pod.Spec.Containers)-1 { + return "", fmt.Errorf("container not found in pod: index %d", containerIndex) + } var shell string var option string if framework.NodeOSDistroIs("windows") { @@ -1068,5 +1071,5 @@ func podContainerExec(pod *v1.Pod, containerIndex int, command string) (string, shell = "/bin/sh" option = "-c" } - return framework.RunKubectl(pod.Namespace, "exec", fmt.Sprintf("--namespace=%s", pod.Namespace), pod.Name, "--container", pod.Spec.Containers[containerIndex].Name, "--", shell, option, command) + return framework.RunKubectl(pod.Namespace, "exec", pod.Name, "--container", pod.Spec.Containers[containerIndex].Name, "--", shell, option, command) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/volume_expand.go b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/volume_expand.go index 42e5253aa75b..c77540ea4aa4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/volume_expand.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/testsuites/volume_expand.go @@ -42,6 +42,12 @@ const ( resizePollInterval = 2 * time.Second // total time to wait for cloudprovider or file system resize to finish totalResizeWaitPeriod = 10 * time.Minute + + // resizedPodStartupTimeout defines time we should wait for pod that uses offline + // resized volume to startup. This time is higher than default PodStartTimeout because + // typically time to detach and then attach a volume is amortized in this time duration. + resizedPodStartupTimeout = 10 * time.Minute + // time to wait for PVC conditions to sync pvcConditionSyncPeriod = 2 * time.Minute ) @@ -214,7 +220,7 @@ func (v *volumeExpandTestSuite) DefineTests(driver TestDriver, pattern testpatte SeLinuxLabel: e2epv.SELinuxLabel, NodeSelection: l.config.ClientNodeSelection, } - l.pod2, err = e2epod.CreateSecPodWithNodeSelection(f.ClientSet, &podConfig, framework.PodStartTimeout) + l.pod2, err = e2epod.CreateSecPodWithNodeSelection(f.ClientSet, &podConfig, resizedPodStartupTimeout) defer func() { err = e2epod.DeletePodWithWait(f.ClientSet, l.pod2) framework.ExpectNoError(err, "while cleaning up pod before exiting resizing test") diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/BUILD b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/BUILD index f8867c90ffd3..bdc78982dcbd 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/BUILD @@ -7,6 +7,7 @@ go_library( srcs = [ "create.go", "deployment.go", + "ebs.go", "framework.go", "host_exec.go", "local.go", @@ -36,9 +37,12 @@ go_library( "//test/e2e/framework/ssh:go_default_library", "//test/e2e/framework/testfiles:go_default_library", "//test/utils/image:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/aws:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/service/ec2:go_default_library", "//vendor/github.com/onsi/ginkgo:go_default_library", "//vendor/github.com/onsi/gomega:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", + "//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", ], ) diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/ebs.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/ebs.go new file mode 100644 index 000000000000..39e223f36aa3 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/ebs.go @@ -0,0 +1,263 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package utils + +import ( + "fmt" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/klog/v2" +) + +const ( + volumeAttachmentStatusPollDelay = 2 * time.Second + volumeAttachmentStatusFactor = 2 + volumeAttachmentStatusSteps = 6 + + // represents expected attachment status of a volume after attach + volumeAttachedStatus = "attached" + + // represents expected attachment status of a volume after detach + volumeDetachedStatus = "detached" +) + +// EBSUtil provides functions to interact with EBS volumes +type EBSUtil struct { + client *ec2.EC2 + validDevices []string +} + +// NewEBSUtil returns an instance of EBSUtil which can be used to +// to interact with EBS volumes +func NewEBSUtil(client *ec2.EC2) *EBSUtil { + ebsUtil := &EBSUtil{client: client} + validDevices := []string{} + for _, firstChar := range []rune{'b', 'c'} { + for i := 'a'; i <= 'z'; i++ { + dev := string([]rune{firstChar, i}) + validDevices = append(validDevices, dev) + } + } + ebsUtil.validDevices = validDevices + return ebsUtil +} + +// AttachDisk attaches an EBS volume to a node. +func (ebs *EBSUtil) AttachDisk(volumeID string, nodeName string) error { + instance, err := findInstanceByNodeName(nodeName, ebs.client) + if err != nil { + return fmt.Errorf("error finding node %s: %v", nodeName, err) + } + err = ebs.waitForAvailable(volumeID) + if err != nil { + return fmt.Errorf("error waiting volume %s to be available: %v", volumeID, err) + } + + device, err := ebs.findFreeDevice(instance) + if err != nil { + return fmt.Errorf("error finding free device on node %s: %v", nodeName, err) + } + hostDevice := "/dev/xvd" + string(device) + attachInput := &ec2.AttachVolumeInput{ + VolumeId: &volumeID, + InstanceId: instance.InstanceId, + Device: &hostDevice, + } + _, err = ebs.client.AttachVolume(attachInput) + if err != nil { + return fmt.Errorf("error attaching volume %s to node %s: %v", volumeID, nodeName, err) + } + return ebs.waitForAttach(volumeID) +} + +func (ebs *EBSUtil) findFreeDevice(instance *ec2.Instance) (string, error) { + deviceMappings := map[string]string{} + + for _, blockDevice := range instance.BlockDeviceMappings { + name := aws.StringValue(blockDevice.DeviceName) + name = strings.TrimPrefix(name, "/dev/sd") + name = strings.TrimPrefix(name, "/dev/xvd") + if len(name) < 1 || len(name) > 2 { + klog.Warningf("Unexpected EBS DeviceName: %q", aws.StringValue(blockDevice.DeviceName)) + } + + deviceMappings[name] = aws.StringValue(blockDevice.Ebs.VolumeId) + } + + for _, device := range ebs.validDevices { + if _, found := deviceMappings[device]; !found { + return device, nil + } + } + return "", fmt.Errorf("no available device") +} + +func (ebs *EBSUtil) waitForAttach(volumeID string) error { + backoff := wait.Backoff{ + Duration: volumeAttachmentStatusPollDelay, + Factor: volumeAttachmentStatusFactor, + Steps: volumeAttachmentStatusSteps, + } + time.Sleep(volumeAttachmentStatusPollDelay) + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + info, err := ebs.describeVolume(volumeID) + if err != nil { + return false, err + } + + if len(info.Attachments) > 1 { + // Shouldn't happen; log so we know if it is + klog.Warningf("Found multiple attachments for volume %q: %v", volumeID, info) + } + attachmentStatus := "" + for _, a := range info.Attachments { + if attachmentStatus != "" { + // Shouldn't happen; log so we know if it is + klog.Warningf("Found multiple attachments for volume %q: %v", volumeID, info) + } + if a.State != nil { + attachmentStatus = *a.State + } else { + // Shouldn't happen; log so we know if it is + klog.Warningf("Ignoring nil attachment state for volume %q: %v", volumeID, a) + } + } + if attachmentStatus == "" { + attachmentStatus = volumeDetachedStatus + } + if attachmentStatus == volumeAttachedStatus { + // Attachment is in requested state, finish waiting + return true, nil + } + return false, nil + }) + return err +} + +func (ebs *EBSUtil) waitForAvailable(volumeID string) error { + backoff := wait.Backoff{ + Duration: volumeAttachmentStatusPollDelay, + Factor: volumeAttachmentStatusFactor, + Steps: volumeAttachmentStatusSteps, + } + time.Sleep(volumeAttachmentStatusPollDelay) + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + info, err := ebs.describeVolume(volumeID) + if err != nil { + return false, err + } + volumeState := aws.StringValue(info.State) + if volumeState != ec2.VolumeStateAvailable { + return false, nil + } + return true, nil + }) + return err +} + +// Gets the full information about this volume from the EC2 API +func (ebs *EBSUtil) describeVolume(volumeID string) (*ec2.Volume, error) { + request := &ec2.DescribeVolumesInput{ + VolumeIds: []*string{&volumeID}, + } + + results := []*ec2.Volume{} + var nextToken *string + for { + response, err := ebs.client.DescribeVolumes(request) + if err != nil { + return nil, err + } + + results = append(results, response.Volumes...) + + nextToken = response.NextToken + if aws.StringValue(nextToken) == "" { + break + } + request.NextToken = nextToken + } + + if len(results) == 0 { + return nil, fmt.Errorf("no volumes found") + } + if len(results) > 1 { + return nil, fmt.Errorf("multiple volumes found") + } + return results[0], nil +} + +func newEc2Filter(name string, value string) *ec2.Filter { + filter := &ec2.Filter{ + Name: aws.String(name), + Values: []*string{ + aws.String(value), + }, + } + return filter +} + +func findInstanceByNodeName(nodeName string, cloud *ec2.EC2) (*ec2.Instance, error) { + filters := []*ec2.Filter{ + newEc2Filter("private-dns-name", nodeName), + } + + request := &ec2.DescribeInstancesInput{ + Filters: filters, + } + + instances, err := describeInstances(request, cloud) + if err != nil { + return nil, err + } + if len(instances) == 0 { + return nil, nil + } + if len(instances) > 1 { + return nil, fmt.Errorf("multiple instances found for name: %s", nodeName) + } + return instances[0], nil +} + +func describeInstances(request *ec2.DescribeInstancesInput, cloud *ec2.EC2) ([]*ec2.Instance, error) { + // Instances are paged + results := []*ec2.Instance{} + var nextToken *string + + for { + response, err := cloud.DescribeInstances(request) + if err != nil { + return nil, fmt.Errorf("error listing AWS instances: %v", err) + } + + for _, reservation := range response.Reservations { + results = append(results, reservation.Instances...) + } + + nextToken = response.NextToken + if nextToken == nil || len(*nextToken) == 0 { + break + } + request.NextToken = nextToken + } + + return results, nil +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go index e081a7e1d2ce..e6ac7027b306 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go @@ -709,9 +709,11 @@ func FindVolumeGlobalMountPoints(hostExec HostExec, node *v1.Node) sets.String { // CreateDriverNamespace creates a namespace for CSI driver installation. // The namespace is still tracked and ensured that gets deleted when test terminates. func CreateDriverNamespace(f *framework.Framework) *v1.Namespace { - ginkgo.By(fmt.Sprintf("Building a driver namespace object, basename %s", f.BaseName)) - namespace, err := f.CreateNamespace(f.BaseName, map[string]string{ - "e2e-framework": f.BaseName, + ginkgo.By(fmt.Sprintf("Building a driver namespace object, basename %s", f.Namespace.Name)) + // The driver namespace will be bound to the test namespace in the prefix + namespace, err := f.CreateNamespace(f.Namespace.Name, map[string]string{ + "e2e-framework": f.BaseName, + "e2e-test-namespace": f.Namespace.Name, }) framework.ExpectNoError(err) diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/vsphere/vsphere_utils.go b/vendor/k8s.io/kubernetes/test/e2e/storage/vsphere/vsphere_utils.go index c80c464efa12..b1623eabfa49 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/vsphere/vsphere_utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/vsphere/vsphere_utils.go @@ -358,7 +358,7 @@ func getVSpherePodSpecWithVolumePaths(volumePaths []string, keyValuelabel map[st func verifyFilesExistOnVSphereVolume(namespace string, podName string, filePaths ...string) { for _, filePath := range filePaths { - _, err := framework.RunKubectl(namespace, "exec", fmt.Sprintf("--namespace=%s", namespace), podName, "--", "/bin/ls", filePath) + _, err := framework.RunKubectl(namespace, "exec", podName, "--", "/bin/ls", filePath) framework.ExpectNoError(err, fmt.Sprintf("failed to verify file: %q on the pod: %q", filePath, podName)) } } @@ -815,7 +815,7 @@ func expectFilesToBeAccessible(namespace string, pods []*v1.Pod, filePaths []str // writeContentToPodFile writes the given content to the specified file. func writeContentToPodFile(namespace, podName, filePath, content string) error { - _, err := framework.RunKubectl(namespace, "exec", fmt.Sprintf("--namespace=%s", namespace), podName, + _, err := framework.RunKubectl(namespace, "exec", podName, "--", "/bin/sh", "-c", fmt.Sprintf("echo '%s' > %s", content, filePath)) return err } @@ -823,7 +823,7 @@ func writeContentToPodFile(namespace, podName, filePath, content string) error { // expectFileContentToMatch checks if a given file contains the specified // content, else fails. func expectFileContentToMatch(namespace, podName, filePath, content string) { - _, err := framework.RunKubectl(namespace, "exec", fmt.Sprintf("--namespace=%s", namespace), podName, + _, err := framework.RunKubectl(namespace, "exec", podName, "--", "/bin/sh", "-c", fmt.Sprintf("grep '%s' %s", content, filePath)) framework.ExpectNoError(err, fmt.Sprintf("failed to match content of file: %q on the pod: %q", filePath, podName)) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/upgrades/apps/replicasets.go b/vendor/k8s.io/kubernetes/test/e2e/upgrades/apps/replicasets.go index f6b838f77fde..f38d6a967400 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/upgrades/apps/replicasets.go +++ b/vendor/k8s.io/kubernetes/test/e2e/upgrades/apps/replicasets.go @@ -87,13 +87,7 @@ func (r *ReplicaSetUpgradeTest) Test(f *framework.Framework, done <-chan struct{ } ginkgo.By(fmt.Sprintf("Waiting for replicaset %s to have all of its replicas ready after upgrade", rsName)) - - err = e2ereplicaset.WaitForReadyReplicaSet(c, ns, rsName) - if err != nil { - framework.DumpAllNamespaceInfo(f.ClientSet, ns) - } - - framework.ExpectNoError(err) + framework.ExpectNoError(e2ereplicaset.WaitForReadyReplicaSet(c, ns, rsName)) // Verify the upgraded RS is active by scaling up the RS to scaleNum and ensuring all pods are Ready ginkgo.By(fmt.Sprintf("Scaling up replicaset %s to %d", rsName, scaleNum)) diff --git a/vendor/k8s.io/kubernetes/test/e2e/upgrades/cassandra.go b/vendor/k8s.io/kubernetes/test/e2e/upgrades/cassandra.go index 2acb054e5b3c..4fbf97f64df7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/upgrades/cassandra.go +++ b/vendor/k8s.io/kubernetes/test/e2e/upgrades/cassandra.go @@ -65,7 +65,7 @@ func cassandraKubectlCreate(ns, file string) { framework.Fail(err.Error()) } input := string(data) - framework.RunKubectlOrDieInput(ns, input, "create", "-f", "-", fmt.Sprintf("--namespace=%s", ns)) + framework.RunKubectlOrDieInput(ns, input, "create", "-f", "-") } // Setup creates a Cassandra StatefulSet and a PDB. It also brings up a tester diff --git a/vendor/k8s.io/kubernetes/test/e2e/upgrades/etcd.go b/vendor/k8s.io/kubernetes/test/e2e/upgrades/etcd.go index 32ca170fd597..243cd7cfb33b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/upgrades/etcd.go +++ b/vendor/k8s.io/kubernetes/test/e2e/upgrades/etcd.go @@ -64,7 +64,7 @@ func kubectlCreate(ns, file string) { framework.Fail(err.Error()) } input := string(data) - framework.RunKubectlOrDieInput(ns, input, "create", "-f", "-", fmt.Sprintf("--namespace=%s", ns)) + framework.RunKubectlOrDieInput(ns, input, "create", "-f", "-") } // Setup creates etcd statefulset and then verifies that the etcd is writable. diff --git a/vendor/k8s.io/kubernetes/test/e2e/upgrades/mysql.go b/vendor/k8s.io/kubernetes/test/e2e/upgrades/mysql.go index 89f735b55efd..edc94a5c2023 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/upgrades/mysql.go +++ b/vendor/k8s.io/kubernetes/test/e2e/upgrades/mysql.go @@ -66,7 +66,7 @@ func mysqlKubectlCreate(ns, file string) { framework.Fail(err.Error()) } input := string(data) - framework.RunKubectlOrDieInput(ns, input, "create", "-f", "-", fmt.Sprintf("--namespace=%s", ns)) + framework.RunKubectlOrDieInput(ns, input, "create", "-f", "-") } func (t *MySQLUpgradeTest) getServiceIP(f *framework.Framework, ns, svcName string) string { diff --git a/vendor/k8s.io/kubernetes/test/integration/BUILD b/vendor/k8s.io/kubernetes/test/integration/BUILD index db7c700523b9..baeeece5b5c0 100644 --- a/vendor/k8s.io/kubernetes/test/integration/BUILD +++ b/vendor/k8s.io/kubernetes/test/integration/BUILD @@ -50,6 +50,7 @@ filegroup( "//test/integration/deployment:all-srcs", "//test/integration/disruption:all-srcs", "//test/integration/dryrun:all-srcs", + "//test/integration/endpoints:all-srcs", "//test/integration/endpointslice:all-srcs", "//test/integration/etcd:all-srcs", "//test/integration/events:all-srcs", diff --git a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go index 179d45f96d4a..5df50a5a5f09 100644 --- a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go +++ b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go @@ -36,12 +36,10 @@ type RegistryList struct { BuildImageRegistry string `yaml:"buildImageRegistry"` InvalidRegistry string `yaml:"invalidRegistry"` GcRegistry string `yaml:"gcRegistry"` + SigStorageRegistry string `yaml:"sigStorageRegistry"` GcrReleaseRegistry string `yaml:"gcrReleaseRegistry"` - // TODO: The last consumer of this has been removed and it should be deprecated - GoogleContainerRegistry string `yaml:"googleContainerRegistry"` PrivateRegistry string `yaml:"privateRegistry"` SampleRegistry string `yaml:"sampleRegistry"` - K8sCSI string `yaml:"k8sCSI"` } // Config holds an images registry, name, and version @@ -73,17 +71,14 @@ func initReg() RegistryList { DockerGluster: "docker.io/gluster", E2eRegistry: "gcr.io/kubernetes-e2e-test-images", E2eVolumeRegistry: "gcr.io/kubernetes-e2e-test-images/volume", - // TODO: After the domain flip, this should instead be k8s.gcr.io/k8s-artifacts-prod/e2e-test-images - PromoterE2eRegistry: "us.gcr.io/k8s-artifacts-prod/e2e-test-images", - BuildImageRegistry: "us.gcr.io/k8s-artifacts-prod/build-image", - InvalidRegistry: "invalid.com/invalid", - GcRegistry: "k8s.gcr.io", - GcrReleaseRegistry: "gcr.io/gke-release", - // TODO: The last consumer of this has been removed and it should be deleted - GoogleContainerRegistry: "gcr.io/google-containers", + PromoterE2eRegistry: "k8s.gcr.io/e2e-test-images", + BuildImageRegistry: "k8s.gcr.io/build-image", + InvalidRegistry: "invalid.com/invalid", + GcRegistry: "k8s.gcr.io", + SigStorageRegistry: "k8s.gcr.io/sig-storage", + GcrReleaseRegistry: "gcr.io/gke-release", PrivateRegistry: "gcr.io/k8s-authenticated-test", SampleRegistry: "gcr.io/google-samples", - K8sCSI: "gcr.io/k8s-staging-csi", } repoList := os.Getenv("KUBE_TEST_REPO_LIST") if repoList == "" { @@ -112,9 +107,9 @@ var ( buildImageRegistry = registry.BuildImageRegistry gcAuthenticatedRegistry = registry.GcAuthenticatedRegistry gcRegistry = registry.GcRegistry + sigStorageRegistry = registry.SigStorageRegistry gcrReleaseRegistry = registry.GcrReleaseRegistry invalidRegistry = registry.InvalidRegistry - k8sCSI = registry.K8sCSI // PrivateRegistry is an image repository that requires authentication PrivateRegistry = registry.PrivateRegistry sampleRegistry = registry.SampleRegistry @@ -215,7 +210,7 @@ func initImageConfigs() map[int]Config { configs[CheckMetadataConcealment] = Config{e2eRegistry, "metadata-concealment", "1.2"} configs[CudaVectorAdd] = Config{e2eRegistry, "cuda-vector-add", "1.0"} configs[CudaVectorAdd2] = Config{e2eRegistry, "cuda-vector-add", "2.0"} - configs[DebianIptables] = Config{buildImageRegistry, "debian-iptables", "v12.1.0"} + configs[DebianIptables] = Config{buildImageRegistry, "debian-iptables", "v12.1.2"} configs[EchoServer] = Config{e2eRegistry, "echoserver", "2.2"} configs[Etcd] = Config{gcRegistry, "etcd", "3.4.9"} configs[GlusterDynamicProvisioner] = Config{dockerGluster, "glusterdynamic-provisioner", "v1.0"} @@ -226,7 +221,7 @@ func initImageConfigs() map[int]Config { configs[JessieDnsutils] = Config{e2eRegistry, "jessie-dnsutils", "1.0"} configs[Kitten] = Config{e2eRegistry, "kitten", "1.0"} configs[Nautilus] = Config{e2eRegistry, "nautilus", "1.0"} - configs[NFSProvisioner] = Config{k8sCSI, "nfs-provisioner", "v2.2.2"} + configs[NFSProvisioner] = Config{sigStorageRegistry, "nfs-provisioner", "v2.2.2"} configs[Nginx] = Config{dockerLibraryRegistry, "nginx", "1.14-alpine"} configs[NginxNew] = Config{dockerLibraryRegistry, "nginx", "1.15-alpine"} configs[Nonewprivs] = Config{e2eRegistry, "nonewprivs", "1.0"} @@ -285,6 +280,8 @@ func ReplaceRegistryInImageURL(imageURL string) (string, error) { registryAndUser = e2eVolumeRegistry case "k8s.gcr.io": registryAndUser = gcRegistry + case "k8s.gcr.io/sig-storage": + registryAndUser = sigStorageRegistry case "gcr.io/k8s-authenticated-test": registryAndUser = PrivateRegistry case "gcr.io/google-samples": @@ -293,8 +290,6 @@ func ReplaceRegistryInImageURL(imageURL string) (string, error) { registryAndUser = gcrReleaseRegistry case "docker.io/library": registryAndUser = dockerLibraryRegistry - case "gcr.io/k8s-staging-csi": - registryAndUser = k8sCSI default: if countParts == 1 { // We assume we found an image from docker hub library diff --git a/vendor/k8s.io/legacy-cloud-providers/aws/aws.go b/vendor/k8s.io/legacy-cloud-providers/aws/aws.go index ece2cf5597c6..6aeaaa7e09c3 100644 --- a/vendor/k8s.io/legacy-cloud-providers/aws/aws.go +++ b/vendor/k8s.io/legacy-cloud-providers/aws/aws.go @@ -257,6 +257,14 @@ const ( filterNodeLimit = 150 ) +const ( + // represents expected attachment status of a volume after attach + volumeAttachedStatus = "attached" + + // represents expected attachment status of a volume after detach + volumeDetachedStatus = "detached" +) + // awsTagNameMasterRoles is a set of well-known AWS tag names that indicate the instance is a master // The major consequence is that it is then not considered for AWS zone discovery for dynamic volume creation. var awsTagNameMasterRoles = sets.NewString("kubernetes.io/role/master", "k8s.io/role/master") @@ -1395,6 +1403,7 @@ func (c *Cloud) Instances() (cloudprovider.Instances, bool) { } // InstancesV2 returns an implementation of InstancesV2 for Amazon Web Services. +// TODO: implement ONLY for external cloud provider func (c *Cloud) InstancesV2() (cloudprovider.InstancesV2, bool) { return nil, false } @@ -1670,31 +1679,6 @@ func (c *Cloud) InstanceShutdownByProviderID(ctx context.Context, providerID str return false, nil } -// InstanceMetadataByProviderID returns metadata of the specified instance. -func (c *Cloud) InstanceMetadataByProviderID(ctx context.Context, providerID string) (*cloudprovider.InstanceMetadata, error) { - instanceID, err := KubernetesInstanceID(providerID).MapToAWSInstanceID() - if err != nil { - return nil, err - } - - instance, err := describeInstance(c.ec2, instanceID) - if err != nil { - return nil, err - } - - // TODO ignore checking whether `*instance.State.Name == ec2.InstanceStateNameTerminated` here. - // If not behave as expected, add it. - addresses, err := extractNodeAddresses(instance) - if err != nil { - return nil, err - } - return &cloudprovider.InstanceMetadata{ - ProviderID: providerID, - Type: aws.StringValue(instance.InstanceType), - NodeAddresses: addresses, - }, nil -} - // InstanceID returns the cloud provider ID of the node with the specified nodeName. func (c *Cloud) InstanceID(ctx context.Context, nodeName types.NodeName) (string, error) { // In the future it is possible to also return an endpoint as: @@ -1967,7 +1951,6 @@ func (c *Cloud) getMountDevice( // AWS API returns consistent result next time (i.e. the volume is detached). status := volumeStatus[mappingVolumeID] klog.Warningf("Got assignment call for already-assigned volume: %s@%s, volume status: %s", mountDevice, mappingVolumeID, status) - return mountDevice, false, fmt.Errorf("volume is still being detached from the node") } return mountDevice, true, nil } @@ -2168,7 +2151,7 @@ func (c *Cloud) applyUnSchedulableTaint(nodeName types.NodeName, reason string) // waitForAttachmentStatus polls until the attachment status is the expected value // On success, it returns the last attachment state. -func (d *awsDisk) waitForAttachmentStatus(status string, expectedInstance, expectedDevice string) (*ec2.VolumeAttachment, error) { +func (d *awsDisk) waitForAttachmentStatus(status string, expectedInstance, expectedDevice string, alreadyAttached bool) (*ec2.VolumeAttachment, error) { backoff := wait.Backoff{ Duration: volumeAttachmentStatusPollDelay, Factor: volumeAttachmentStatusFactor, @@ -2193,7 +2176,7 @@ func (d *awsDisk) waitForAttachmentStatus(status string, expectedInstance, expec if err != nil { // The VolumeNotFound error is special -- we don't need to wait for it to repeat if isAWSErrorVolumeNotFound(err) { - if status == "detached" { + if status == volumeDetachedStatus { // The disk doesn't exist, assume it's detached, log warning and stop waiting klog.Warningf("Waiting for volume %q to be detached but the volume does not exist", d.awsID) stateStr := "detached" @@ -2202,7 +2185,7 @@ func (d *awsDisk) waitForAttachmentStatus(status string, expectedInstance, expec } return true, nil } - if status == "attached" { + if status == volumeAttachedStatus { // The disk doesn't exist, complain, give up waiting and report error klog.Warningf("Waiting for volume %q to be attached but the volume does not exist", d.awsID) return false, err @@ -2237,7 +2220,7 @@ func (d *awsDisk) waitForAttachmentStatus(status string, expectedInstance, expec } } if attachmentStatus == "" { - attachmentStatus = "detached" + attachmentStatus = volumeDetachedStatus } if attachment != nil { // AWS eventual consistency can go back in time. @@ -2266,6 +2249,13 @@ func (d *awsDisk) waitForAttachmentStatus(status string, expectedInstance, expec } } + // if we expected volume to be attached and it was reported as already attached via DescribeInstance call + // but DescribeVolume told us volume is detached, we will short-circuit this long wait loop and return error + // so as AttachDisk can be retried without waiting for 20 minutes. + if (status == volumeAttachedStatus) && alreadyAttached && (attachmentStatus != status) { + return false, fmt.Errorf("attachment of disk %q failed, expected device to be attached but was %s", d.name, attachmentStatus) + } + if attachmentStatus == status { // Attachment is in requested state, finish waiting return true, nil @@ -2411,7 +2401,7 @@ func (c *Cloud) AttachDisk(diskName KubernetesVolumeID, nodeName types.NodeName) klog.V(2).Infof("AttachVolume volume=%q instance=%q request returned %v", disk.awsID, awsInstance.awsID, attachResponse) } - attachment, err := disk.waitForAttachmentStatus("attached", awsInstance.awsID, ec2Device) + attachment, err := disk.waitForAttachmentStatus("attached", awsInstance.awsID, ec2Device, alreadyAttached) if err != nil { if err == wait.ErrWaitTimeout { @@ -2489,7 +2479,7 @@ func (c *Cloud) DetachDisk(diskName KubernetesVolumeID, nodeName types.NodeName) return "", errors.New("no response from DetachVolume") } - attachment, err := diskInfo.disk.waitForAttachmentStatus("detached", awsInstance.awsID, "") + attachment, err := diskInfo.disk.waitForAttachmentStatus("detached", awsInstance.awsID, "", false) if err != nil { return "", err } @@ -4797,7 +4787,7 @@ func setNodeDisk( } func getInitialAttachDetachDelay(status string) time.Duration { - if status == "detached" { + if status == volumeDetachedStatus { return volumeDetachmentStatusInitialDelay } return volumeAttachmentStatusInitialDelay diff --git a/vendor/k8s.io/legacy-cloud-providers/azure/azure.go b/vendor/k8s.io/legacy-cloud-providers/azure/azure.go index 14032092ed49..fcccf5786804 100644 --- a/vendor/k8s.io/legacy-cloud-providers/azure/azure.go +++ b/vendor/k8s.io/legacy-cloud-providers/azure/azure.go @@ -665,6 +665,7 @@ func (az *Cloud) Instances() (cloudprovider.Instances, bool) { } // InstancesV2 returns an instancesV2 interface. Also returns true if the interface is supported, false otherwise. +// TODO: implement ONLY for external cloud provider func (az *Cloud) InstancesV2() (cloudprovider.InstancesV2, bool) { return nil, false } diff --git a/vendor/k8s.io/legacy-cloud-providers/azure/azure_instances.go b/vendor/k8s.io/legacy-cloud-providers/azure/azure_instances.go index b06c16a618c0..a0f19f85fbe4 100644 --- a/vendor/k8s.io/legacy-cloud-providers/azure/azure_instances.go +++ b/vendor/k8s.io/legacy-cloud-providers/azure/azure_instances.go @@ -239,80 +239,6 @@ func (az *Cloud) InstanceShutdownByProviderID(ctx context.Context, providerID st return status == vmPowerStateStopped || status == vmPowerStateDeallocated || status == vmPowerStateDeallocating, nil } -// InstanceMetadataByProviderID returns metadata of the specified instance. -// InstanceMetadataByProviderID is part of InstancesV2 interface and is only used in cloud node-controller. -func (az *Cloud) InstanceMetadataByProviderID(ctx context.Context, providerID string) (*cloudprovider.InstanceMetadata, error) { - if providerID == "" { - return nil, errNodeNotInitialized - } - - // Returns nil for unmanaged nodes because azure cloud provider couldn't fetch information for them. - if az.IsNodeUnmanagedByProviderID(providerID) { - klog.V(4).Infof("NodeAddressesByProviderID: omitting unmanaged node %q", providerID) - return nil, nil - } - - nodeName, err := az.vmSet.GetNodeNameByProviderID(providerID) - if err != nil { - return nil, err - } - - md := &cloudprovider.InstanceMetadata{} - md.ProviderID = providerID - if az.UseInstanceMetadata { - metadata, err := az.metadata.GetMetadata(azcache.CacheReadTypeDefault) - if err != nil { - return nil, err - } - - if metadata.Compute == nil || metadata.Network == nil { - return nil, fmt.Errorf("failure of getting instance metadata") - } - - isLocalInstance, err := az.isCurrentInstance(nodeName, metadata.Compute.Name) - if err != nil { - return nil, err - } - - // Not local instance, get metadata from Azure ARM API. - if !isLocalInstance { - if az.vmSet != nil { - if md.Type, err = az.vmSet.GetInstanceTypeByNodeName(string(nodeName)); err != nil { - return nil, err - } - if md.NodeAddresses, err = az.addressGetter(nodeName); err != nil { - return nil, err - } - return md, nil - } - // vmSet == nil indicates credentials are not provided. - return nil, fmt.Errorf("no credentials provided for Azure cloud provider") - } - - // Get instance metadata from IMDS for local instance. - if metadata.Compute.VMSize != "" { - md.Type = metadata.Compute.VMSize - } else { - if md.Type, err = az.vmSet.GetInstanceTypeByNodeName(string(nodeName)); err != nil { - return nil, err - } - } - if md.NodeAddresses, err = az.getLocalInstanceNodeAddresses(metadata.Network.Interface, string(nodeName)); err != nil { - return nil, err - } - return md, nil - } - - // Get instance metadata from ARM API when UseInstanceMetadata is disabled. - if md.Type, err = az.vmSet.GetInstanceTypeByNodeName(string(nodeName)); err != nil { - return nil, err - } - if md.NodeAddresses, err = az.addressGetter(nodeName); err != nil { - return nil, err - } - return md, err -} - func (az *Cloud) isCurrentInstance(name types.NodeName, metadataVMName string) (bool, error) { var err error nodeName := mapNodeNameToVMName(name) diff --git a/vendor/k8s.io/legacy-cloud-providers/azure/azure_vmss.go b/vendor/k8s.io/legacy-cloud-providers/azure/azure_vmss.go index 7670608ca142..c1ce257c5d3f 100644 --- a/vendor/k8s.io/legacy-cloud-providers/azure/azure_vmss.go +++ b/vendor/k8s.io/legacy-cloud-providers/azure/azure_vmss.go @@ -61,6 +61,13 @@ type vmssMetaInfo struct { resourceGroup string } +// nodeIdentity identifies a node within a subscription. +type nodeIdentity struct { + resourceGroup string + vmssName string + nodeName string +} + // scaleSet implements VMSet interface for Azure scale set. type scaleSet struct { *Cloud @@ -70,18 +77,22 @@ type scaleSet struct { availabilitySet VMSet vmssCache *azcache.TimedCache - vmssVMCache *azcache.TimedCache + vmssVMCache *sync.Map // [resourcegroup/vmssname]*azcache.TimedCache availabilitySetNodesCache *azcache.TimedCache } // newScaleSet creates a new scaleSet. func newScaleSet(az *Cloud) (VMSet, error) { - var err error + if az.Config.VmssVirtualMachinesCacheTTLInSeconds == 0 { + az.Config.VmssVirtualMachinesCacheTTLInSeconds = vmssVirtualMachinesCacheTTLDefaultInSeconds + } ss := &scaleSet{ Cloud: az, availabilitySet: newAvailabilitySet(az), + vmssVMCache: &sync.Map{}, } + var err error if !ss.DisableAvailabilitySetNodes { ss.availabilitySetNodesCache, err = ss.newAvailabilitySetNodesCache() if err != nil { @@ -94,11 +105,6 @@ func newScaleSet(az *Cloud) (VMSet, error) { return nil, err } - ss.vmssVMCache, err = ss.newVMSSVirtualMachinesCache() - if err != nil { - return nil, err - } - return ss, nil } @@ -139,12 +145,17 @@ func (ss *scaleSet) getVMSS(vmssName string, crt azcache.AzureCacheReadType) (*c return vmss, nil } -// getVmssVM gets virtualMachineScaleSetVM by nodeName from cache. -// It returns cloudprovider.InstanceNotFound if node does not belong to any scale sets. -func (ss *scaleSet) getVmssVM(nodeName string, crt azcache.AzureCacheReadType) (string, string, *compute.VirtualMachineScaleSetVM, error) { +// getVmssVMByNodeIdentity find virtualMachineScaleSetVM by nodeIdentity, using node's parent VMSS cache. +// Returns cloudprovider.InstanceNotFound if the node does not belong to the scale set named in nodeIdentity. +func (ss *scaleSet) getVmssVMByNodeIdentity(node *nodeIdentity, crt azcache.AzureCacheReadType) (string, string, *compute.VirtualMachineScaleSetVM, error) { + cacheKey, cache, err := ss.getVMSSVMCache(node.resourceGroup, node.vmssName) + if err != nil { + return "", "", nil, err + } + getter := func(nodeName string, crt azcache.AzureCacheReadType) (string, string, *compute.VirtualMachineScaleSetVM, bool, error) { var found bool - cached, err := ss.vmssVMCache.Get(vmssVirtualMachinesKey, crt) + cached, err := cache.Get(cacheKey, crt) if err != nil { return "", "", nil, found, err } @@ -159,19 +170,19 @@ func (ss *scaleSet) getVmssVM(nodeName string, crt azcache.AzureCacheReadType) ( return "", "", nil, found, nil } - _, err := getScaleSetVMInstanceID(nodeName) + _, err = getScaleSetVMInstanceID(node.nodeName) if err != nil { return "", "", nil, err } - vmssName, instanceID, vm, found, err := getter(nodeName, crt) + vmssName, instanceID, vm, found, err := getter(node.nodeName, crt) if err != nil { return "", "", nil, err } if !found { - klog.V(2).Infof("Couldn't find VMSS VM with nodeName %s, refreshing the cache", nodeName) - vmssName, instanceID, vm, found, err = getter(nodeName, azcache.CacheReadTypeForceRefresh) + klog.V(2).Infof("Couldn't find VMSS VM with nodeName %s, refreshing the cache", node.nodeName) + vmssName, instanceID, vm, found, err = getter(node.nodeName, azcache.CacheReadTypeForceRefresh) if err != nil { return "", "", nil, err } @@ -187,6 +198,17 @@ func (ss *scaleSet) getVmssVM(nodeName string, crt azcache.AzureCacheReadType) ( return vmssName, instanceID, vm, nil } +// getVmssVM gets virtualMachineScaleSetVM by nodeName from cache. +// Returns cloudprovider.InstanceNotFound if nodeName does not belong to any scale set. +func (ss *scaleSet) getVmssVM(nodeName string, crt azcache.AzureCacheReadType) (string, string, *compute.VirtualMachineScaleSetVM, error) { + node, err := ss.getNodeIdentityByNodeName(nodeName, crt) + if err != nil { + return "", "", nil, err + } + + return ss.getVmssVMByNodeIdentity(node, crt) +} + // GetPowerStatusByNodeName returns the power state of the specified node. func (ss *scaleSet) GetPowerStatusByNodeName(name string) (powerState string, err error) { managedByAS, err := ss.isNodeManagedByAvailabilitySet(name, azcache.CacheReadTypeUnsafe) @@ -222,8 +244,13 @@ func (ss *scaleSet) GetPowerStatusByNodeName(name string) (powerState string, er // getCachedVirtualMachineByInstanceID gets scaleSetVMInfo from cache. // The node must belong to one of scale sets. func (ss *scaleSet) getVmssVMByInstanceID(resourceGroup, scaleSetName, instanceID string, crt azcache.AzureCacheReadType) (*compute.VirtualMachineScaleSetVM, error) { + cacheKey, cache, err := ss.getVMSSVMCache(resourceGroup, scaleSetName) + if err != nil { + return nil, err + } + getter := func(crt azcache.AzureCacheReadType) (vm *compute.VirtualMachineScaleSetVM, found bool, err error) { - cached, err := ss.vmssVMCache.Get(vmssVirtualMachinesKey, crt) + cached, err := cache.Get(cacheKey, crt) if err != nil { return nil, false, err } @@ -259,6 +286,13 @@ func (ss *scaleSet) getVmssVMByInstanceID(resourceGroup, scaleSetName, instanceI if found && vm != nil { return vm, nil } + if found && vm == nil { + klog.V(2).Infof("Couldn't find VMSS VM with scaleSetName %q and instanceID %q, refreshing the cache if it is expired", scaleSetName, instanceID) + vm, found, err = getter(azcache.CacheReadTypeDefault) + if err != nil { + return nil, err + } + } if !found || vm == nil { return nil, cloudprovider.InstanceNotFound } @@ -590,6 +624,66 @@ func (ss *scaleSet) listScaleSets(resourceGroup string) ([]string, error) { return ssNames, nil } +// getNodeIdentityByNodeName use the VMSS cache to find a node's resourcegroup and vmss, returned in a nodeIdentity. +func (ss *scaleSet) getNodeIdentityByNodeName(nodeName string, crt azcache.AzureCacheReadType) (*nodeIdentity, error) { + getter := func(nodeName string, crt azcache.AzureCacheReadType) (*nodeIdentity, error) { + node := &nodeIdentity{ + nodeName: nodeName, + } + + cached, err := ss.vmssCache.Get(vmssKey, crt) + if err != nil { + return nil, err + } + + vmsses := cached.(*sync.Map) + vmsses.Range(func(key, value interface{}) bool { + v := value.(*vmssEntry) + if v.vmss.Name == nil { + return true + } + + vmssPrefix := *v.vmss.Name + if v.vmss.VirtualMachineProfile != nil && + v.vmss.VirtualMachineProfile.OsProfile != nil && + v.vmss.VirtualMachineProfile.OsProfile.ComputerNamePrefix != nil { + vmssPrefix = *v.vmss.VirtualMachineProfile.OsProfile.ComputerNamePrefix + } + + if strings.EqualFold(vmssPrefix, nodeName[:len(nodeName)-6]) { + node.vmssName = *v.vmss.Name + node.resourceGroup = v.resourceGroup + return false + } + + return true + }) + return node, nil + } + + if _, err := getScaleSetVMInstanceID(nodeName); err != nil { + return nil, err + } + + node, err := getter(nodeName, crt) + if err != nil { + return nil, err + } + if node.vmssName != "" { + return node, nil + } + + klog.V(2).Infof("Couldn't find VMSS for node %s, refreshing the cache", nodeName) + node, err = getter(nodeName, azcache.CacheReadTypeForceRefresh) + if err != nil { + return nil, err + } + if node.vmssName == "" { + return nil, cloudprovider.InstanceNotFound + } + return node, nil +} + // listScaleSetVMs lists VMs belonging to the specified scale set. func (ss *scaleSet) listScaleSetVMs(scaleSetName, resourceGroup string) ([]compute.VirtualMachineScaleSetVM, error) { ctx, cancel := getContextWithCancel() diff --git a/vendor/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go b/vendor/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go index 94a85aade66e..7cea160c0444 100644 --- a/vendor/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go +++ b/vendor/k8s.io/legacy-cloud-providers/azure/azure_vmss_cache.go @@ -20,6 +20,7 @@ package azure import ( "context" + "fmt" "strings" "sync" "time" @@ -36,7 +37,6 @@ var ( vmssNameSeparator = "_" vmssKey = "k8svmssKey" - vmssVirtualMachinesKey = "k8svmssVirtualMachinesKey" availabilitySetNodesKey = "k8sAvailabilitySetNodesKey" availabilitySetNodesCacheTTLDefaultInSeconds = 900 @@ -53,8 +53,9 @@ type vmssVirtualMachinesEntry struct { } type vmssEntry struct { - vmss *compute.VirtualMachineScaleSet - lastUpdate time.Time + vmss *compute.VirtualMachineScaleSet + resourceGroup string + lastUpdate time.Time } func (ss *scaleSet) newVMSSCache() (*azcache.TimedCache, error) { @@ -80,8 +81,9 @@ func (ss *scaleSet) newVMSSCache() (*azcache.TimedCache, error) { continue } localCache.Store(*scaleSet.Name, &vmssEntry{ - vmss: &scaleSet, - lastUpdate: time.Now().UTC(), + vmss: &scaleSet, + resourceGroup: resourceGroup, + lastUpdate: time.Now().UTC(), }) } } @@ -109,15 +111,60 @@ func extractVmssVMName(name string) (string, string, error) { return ssName, instanceID, nil } -func (ss *scaleSet) newVMSSVirtualMachinesCache() (*azcache.TimedCache, error) { +// getVMSSVMCache returns an *azcache.TimedCache and cache key for a VMSS (creating that cache if new). +func (ss *scaleSet) getVMSSVMCache(resourceGroup, vmssName string) (string, *azcache.TimedCache, error) { + cacheKey := strings.ToLower(fmt.Sprintf("%s/%s", resourceGroup, vmssName)) + if entry, ok := ss.vmssVMCache.Load(cacheKey); ok { + cache := entry.(*azcache.TimedCache) + return cacheKey, cache, nil + } + + cache, err := ss.newVMSSVirtualMachinesCache(resourceGroup, vmssName, cacheKey) + if err != nil { + return "", nil, err + } + ss.vmssVMCache.Store(cacheKey, cache) + return cacheKey, cache, nil +} + +// gcVMSSVMCache delete stale VMSS VMs caches from deleted VMSSes. +func (ss *scaleSet) gcVMSSVMCache() error { + cached, err := ss.vmssCache.Get(vmssKey, azcache.CacheReadTypeUnsafe) + if err != nil { + return err + } + + vmsses := cached.(*sync.Map) + removed := map[string]bool{} + ss.vmssVMCache.Range(func(key, value interface{}) bool { + cacheKey := key.(string) + vlistIdx := cacheKey[strings.LastIndex(cacheKey, "/")+1:] + if _, ok := vmsses.Load(vlistIdx); !ok { + removed[cacheKey] = true + } + return true + }) + + for key := range removed { + ss.vmssVMCache.Delete(key) + } + + return nil +} + +// newVMSSVirtualMachinesCache instanciates a new VMs cache for VMs belonging to the provided VMSS. +func (ss *scaleSet) newVMSSVirtualMachinesCache(resourceGroupName, vmssName, cacheKey string) (*azcache.TimedCache, error) { + vmssVirtualMachinesCacheTTL := time.Duration(ss.Config.VmssVirtualMachinesCacheTTLInSeconds) * time.Second + getter := func(key string) (interface{}, error) { localCache := &sync.Map{} // [nodeName]*vmssVirtualMachinesEntry oldCache := make(map[string]vmssVirtualMachinesEntry) - if ss.vmssVMCache != nil { + if vmssCache, ok := ss.vmssVMCache.Load(cacheKey); ok { // get old cache before refreshing the cache - entry, exists, err := ss.vmssVMCache.Store.GetByKey(vmssVirtualMachinesKey) + cache := vmssCache.(*azcache.TimedCache) + entry, exists, err := cache.Store.GetByKey(cacheKey) if err != nil { return nil, err } @@ -133,95 +180,94 @@ func (ss *scaleSet) newVMSSVirtualMachinesCache() (*azcache.TimedCache, error) { } } - allResourceGroups, err := ss.GetResourceGroups() + vms, err := ss.listScaleSetVMs(vmssName, resourceGroupName) if err != nil { return nil, err } - for _, resourceGroup := range allResourceGroups.List() { - scaleSetNames, err := ss.listScaleSets(resourceGroup) - if err != nil { - return nil, err + for i := range vms { + vm := vms[i] + if vm.OsProfile == nil || vm.OsProfile.ComputerName == nil { + klog.Warningf("failed to get computerName for vmssVM (%q)", vmssName) + continue } - for _, ssName := range scaleSetNames { - vms, err := ss.listScaleSetVMs(ssName, resourceGroup) - if err != nil { - return nil, err - } - - for i := range vms { - vm := vms[i] - if vm.OsProfile == nil || vm.OsProfile.ComputerName == nil { - klog.Warningf("failed to get computerName for vmssVM (%q)", ssName) - continue - } - - computerName := strings.ToLower(*vm.OsProfile.ComputerName) - vmssVMCacheEntry := &vmssVirtualMachinesEntry{ - resourceGroup: resourceGroup, - vmssName: ssName, - instanceID: to.String(vm.InstanceID), - virtualMachine: &vm, - lastUpdate: time.Now().UTC(), - } - // set cache entry to nil when the VM is under deleting. - if vm.VirtualMachineScaleSetVMProperties != nil && - strings.EqualFold(to.String(vm.VirtualMachineScaleSetVMProperties.ProvisioningState), string(compute.ProvisioningStateDeleting)) { - klog.V(4).Infof("VMSS virtualMachine %q is under deleting, setting its cache to nil", computerName) - vmssVMCacheEntry.virtualMachine = nil - } - localCache.Store(computerName, vmssVMCacheEntry) - - delete(oldCache, computerName) - } + computerName := strings.ToLower(*vm.OsProfile.ComputerName) + vmssVMCacheEntry := &vmssVirtualMachinesEntry{ + resourceGroup: resourceGroupName, + vmssName: vmssName, + instanceID: to.String(vm.InstanceID), + virtualMachine: &vm, + lastUpdate: time.Now().UTC(), + } + // set cache entry to nil when the VM is under deleting. + if vm.VirtualMachineScaleSetVMProperties != nil && + strings.EqualFold(to.String(vm.VirtualMachineScaleSetVMProperties.ProvisioningState), string(compute.ProvisioningStateDeleting)) { + klog.V(4).Infof("VMSS virtualMachine %q is under deleting, setting its cache to nil", computerName) + vmssVMCacheEntry.virtualMachine = nil } + localCache.Store(computerName, vmssVMCacheEntry) - // add old missing cache data with nil entries to prevent aggressive - // ARM calls during cache invalidation - for name, vmEntry := range oldCache { - // if the nil cache entry has existed for 15 minutes in the cache - // then it should not be added back to the cache - if vmEntry.virtualMachine == nil && time.Since(vmEntry.lastUpdate) > 15*time.Minute { - klog.V(5).Infof("ignoring expired entries from old cache for %s", name) - continue - } - lastUpdate := time.Now().UTC() - if vmEntry.virtualMachine == nil { - // if this is already a nil entry then keep the time the nil - // entry was first created, so we can cleanup unwanted entries - lastUpdate = vmEntry.lastUpdate - } + delete(oldCache, computerName) + } - klog.V(5).Infof("adding old entries to new cache for %s", name) - localCache.Store(name, &vmssVirtualMachinesEntry{ - resourceGroup: vmEntry.resourceGroup, - vmssName: vmEntry.vmssName, - instanceID: vmEntry.instanceID, - virtualMachine: nil, - lastUpdate: lastUpdate, - }) + // add old missing cache data with nil entries to prevent aggressive + // ARM calls during cache invalidation + for name, vmEntry := range oldCache { + // if the nil cache entry has existed for vmssVirtualMachinesCacheTTL in the cache + // then it should not be added back to the cache + if vmEntry.virtualMachine == nil && time.Since(vmEntry.lastUpdate) > vmssVirtualMachinesCacheTTL { + klog.V(5).Infof("ignoring expired entries from old cache for %s", name) + continue + } + lastUpdate := time.Now().UTC() + if vmEntry.virtualMachine == nil { + // if this is already a nil entry then keep the time the nil + // entry was first created, so we can cleanup unwanted entries + lastUpdate = vmEntry.lastUpdate } + + klog.V(5).Infof("adding old entries to new cache for %s", name) + localCache.Store(name, &vmssVirtualMachinesEntry{ + resourceGroup: vmEntry.resourceGroup, + vmssName: vmEntry.vmssName, + instanceID: vmEntry.instanceID, + virtualMachine: nil, + lastUpdate: lastUpdate, + }) } return localCache, nil } - if ss.Config.VmssVirtualMachinesCacheTTLInSeconds == 0 { - ss.Config.VmssVirtualMachinesCacheTTLInSeconds = vmssVirtualMachinesCacheTTLDefaultInSeconds - } - return azcache.NewTimedcache(time.Duration(ss.Config.VmssVirtualMachinesCacheTTLInSeconds)*time.Second, getter) + return azcache.NewTimedcache(vmssVirtualMachinesCacheTTL, getter) } func (ss *scaleSet) deleteCacheForNode(nodeName string) error { - cached, err := ss.vmssVMCache.Get(vmssVirtualMachinesKey, azcache.CacheReadTypeUnsafe) + node, err := ss.getNodeIdentityByNodeName(nodeName, azcache.CacheReadTypeUnsafe) if err != nil { klog.Errorf("deleteCacheForNode(%s) failed with error: %v", nodeName, err) return err } - virtualMachines := cached.(*sync.Map) + cacheKey, timedcache, err := ss.getVMSSVMCache(node.resourceGroup, node.vmssName) + if err != nil { + klog.Errorf("deleteCacheForNode(%s) failed with error: %v", nodeName, err) + return err + } + + vmcache, err := timedcache.Get(cacheKey, azcache.CacheReadTypeUnsafe) + if err != nil { + klog.Errorf("deleteCacheForNode(%s) failed with error: %v", nodeName, err) + return err + } + virtualMachines := vmcache.(*sync.Map) virtualMachines.Delete(nodeName) + + if err := ss.gcVMSSVMCache(); err != nil { + klog.Errorf("deleteCacheForNode(%s) failed to gc stale vmss caches: %v", nodeName, err) + } + return nil } diff --git a/vendor/k8s.io/legacy-cloud-providers/gce/gce.go b/vendor/k8s.io/legacy-cloud-providers/gce/gce.go index de703e8f6031..5b31c0f4d47d 100644 --- a/vendor/k8s.io/legacy-cloud-providers/gce/gce.go +++ b/vendor/k8s.io/legacy-cloud-providers/gce/gce.go @@ -669,6 +669,7 @@ func (g *Cloud) Instances() (cloudprovider.Instances, bool) { } // InstancesV2 returns an implementation of InstancesV2 for Google Compute Engine. +// TODO: implement ONLY for external cloud provider func (g *Cloud) InstancesV2() (cloudprovider.InstancesV2, bool) { return nil, false } diff --git a/vendor/k8s.io/legacy-cloud-providers/gce/gce_instances.go b/vendor/k8s.io/legacy-cloud-providers/gce/gce_instances.go index 7cf3282307f2..6a1e1acb9f97 100644 --- a/vendor/k8s.io/legacy-cloud-providers/gce/gce_instances.go +++ b/vendor/k8s.io/legacy-cloud-providers/gce/gce_instances.go @@ -210,36 +210,6 @@ func (g *Cloud) InstanceShutdownByProviderID(ctx context.Context, providerID str return false, cloudprovider.NotImplemented } -// InstanceMetadataByProviderID returns metadata of the specified instance. -func (g *Cloud) InstanceMetadataByProviderID(ctx context.Context, providerID string) (*cloudprovider.InstanceMetadata, error) { - timeoutCtx, cancel := context.WithTimeout(ctx, 1*time.Hour) - defer cancel() - - if providerID == "" { - return nil, fmt.Errorf("couldn't compute InstanceMetadata for empty providerID") - } - - _, zone, name, err := splitProviderID(providerID) - if err != nil { - return nil, err - } - - instance, err := g.c.Instances().Get(timeoutCtx, meta.ZonalKey(canonicalizeInstanceName(name), zone)) - if err != nil { - return nil, fmt.Errorf("error while querying for providerID %q: %v", providerID, err) - } - - addresses, err := nodeAddressesFromInstance(instance) - if err != nil { - return nil, err - } - return &cloudprovider.InstanceMetadata{ - ProviderID: providerID, - Type: lastComponent(instance.MachineType), - NodeAddresses: addresses, - }, nil -} - func nodeAddressesFromInstance(instance *compute.Instance) ([]v1.NodeAddress, error) { if len(instance.NetworkInterfaces) < 1 { return nil, fmt.Errorf("could not find network interfaces for instanceID %q", instance.Id) diff --git a/vendor/k8s.io/legacy-cloud-providers/openstack/openstack_instances.go b/vendor/k8s.io/legacy-cloud-providers/openstack/openstack_instances.go index c2caff1db190..3b9b62f6183b 100644 --- a/vendor/k8s.io/legacy-cloud-providers/openstack/openstack_instances.go +++ b/vendor/k8s.io/legacy-cloud-providers/openstack/openstack_instances.go @@ -73,6 +73,7 @@ func (os *OpenStack) Instances() (cloudprovider.Instances, bool) { } // InstancesV2 returns an implementation of InstancesV2 for OpenStack. +// TODO: implement ONLY for external cloud provider func (os *OpenStack) InstancesV2() (cloudprovider.InstancesV2, bool) { return nil, false } @@ -204,37 +205,6 @@ func (i *Instances) InstanceShutdownByProviderID(ctx context.Context, providerID return false, nil } -// InstanceMetadataByProviderID returns metadata of the specified instance. -func (i *Instances) InstanceMetadataByProviderID(ctx context.Context, providerID string) (*cloudprovider.InstanceMetadata, error) { - if providerID == "" { - return nil, fmt.Errorf("couldn't compute InstanceMetadata for empty providerID") - } - - instanceID, err := instanceIDFromProviderID(providerID) - if err != nil { - return nil, err - } - srv, err := servers.Get(i.compute, instanceID).Extract() - if err != nil { - return nil, err - } - - instanceType, err := srvInstanceType(srv) - if err != nil { - return nil, err - } - addresses, err := nodeAddresses(srv) - if err != nil { - return nil, err - } - - return &cloudprovider.InstanceMetadata{ - ProviderID: providerID, - Type: instanceType, - NodeAddresses: addresses, - }, nil -} - // InstanceID returns the kubelet's cloud provider ID. func (os *OpenStack) InstanceID() (string, error) { if len(os.localInstanceID) == 0 { @@ -257,7 +227,7 @@ func (i *Instances) InstanceID(ctx context.Context, name types.NodeName) (string } localName := types.NodeName(md.Name) if localName == name { - return md.UUID, nil + return "/" + md.UUID, nil } srv, err := getServerByName(i.compute, name) diff --git a/vendor/k8s.io/legacy-cloud-providers/vsphere/vsphere.go b/vendor/k8s.io/legacy-cloud-providers/vsphere/vsphere.go index d7b391518552..12da586427a6 100644 --- a/vendor/k8s.io/legacy-cloud-providers/vsphere/vsphere.go +++ b/vendor/k8s.io/legacy-cloud-providers/vsphere/vsphere.go @@ -561,6 +561,7 @@ func (vs *VSphere) Instances() (cloudprovider.Instances, bool) { } // InstancesV2 returns an implementation of InstancesV2 for vSphere. +// TODO: implement ONLY for external cloud provider func (vs *VSphere) InstancesV2() (cloudprovider.InstancesV2, bool) { return nil, false } @@ -797,41 +798,6 @@ func (vs *VSphere) InstanceShutdownByProviderID(ctx context.Context, providerID return !isActive, nil } -// InstanceMetadataByProviderID returns metadata of the specified instance. -func (vs *VSphere) InstanceMetadataByProviderID(ctx context.Context, providerID string) (*cloudprovider.InstanceMetadata, error) { - if providerID == "" { - return nil, fmt.Errorf("couldn't compute InstanceMetadata for empty providerID") - } - - // TODO dropped get nodeName by GetNodeNameFromProviderID here. If it not behave as expected, - // get nodeName by vm.GetNodeNameFromProviderID. - return vs.instanceMetadataByNodeName(ctx, convertToK8sType(providerID)) -} - -func (vs *VSphere) instanceMetadataByNodeName(ctx context.Context, nodeName k8stypes.NodeName) (*cloudprovider.InstanceMetadata, error) { - if vs.hostName == convertToString(nodeName) { - addresses, err := vs.getNodeAddressesFromLocalIP() - if err != nil { - return nil, err - } - return &cloudprovider.InstanceMetadata{ - ProviderID: vs.vmUUID, - Type: "", - NodeAddresses: addresses, - }, nil - } - - addresses, err := vs.getNodeAddressesFromVM(ctx, nodeName) - if err != nil { - return nil, err - } - return &cloudprovider.InstanceMetadata{ - ProviderID: vs.vmUUID, - Type: "", - NodeAddresses: addresses, - }, nil -} - // InstanceID returns the cloud provider ID of the node with the specified Name. func (vs *VSphere) InstanceID(ctx context.Context, nodeName k8stypes.NodeName) (string, error) { diff --git a/vendor/modules.txt b/vendor/modules.txt index 50cb80d780af..d28d6cfc8cb2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -41,7 +41,7 @@ github.com/MakeNowJust/heredoc # github.com/Microsoft/go-winio v0.4.15-0.20200113171025-3fe6c5262873 => github.com/Microsoft/go-winio v0.4.14 github.com/Microsoft/go-winio github.com/Microsoft/go-winio/pkg/guid -# github.com/Microsoft/hcsshim v0.8.9 => github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d +# github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990 => github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d github.com/Microsoft/hcsshim github.com/Microsoft/hcsshim/hcn github.com/Microsoft/hcsshim/internal/cni @@ -246,7 +246,7 @@ github.com/emirpasic/gods/trees/binaryheap github.com/emirpasic/gods/utils # github.com/euank/go-kmsg-parser v2.0.0+incompatible => github.com/euank/go-kmsg-parser v2.0.0+incompatible github.com/euank/go-kmsg-parser/kmsgparser -# github.com/evanphx/json-patch v4.2.0+incompatible => github.com/evanphx/json-patch v4.2.0+incompatible +# github.com/evanphx/json-patch v4.9.0+incompatible => github.com/evanphx/json-patch v4.2.0+incompatible github.com/evanphx/json-patch # github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d => github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d github.com/exponent-io/jsonpath @@ -601,7 +601,7 @@ github.com/opencontainers/runtime-spec/specs-go github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalk -# github.com/openshift/api v0.0.0-20200722204502-c33fd0aa6ffa +# github.com/openshift/api v0.0.0-20200829102639-8a3a835f1acf github.com/openshift/api github.com/openshift/api/annotations github.com/openshift/api/apps @@ -614,6 +614,8 @@ github.com/openshift/api/config github.com/openshift/api/config/v1 github.com/openshift/api/console github.com/openshift/api/console/v1 +github.com/openshift/api/helm +github.com/openshift/api/helm/v1beta1 github.com/openshift/api/image github.com/openshift/api/image/docker10 github.com/openshift/api/image/dockerpre012 @@ -654,7 +656,7 @@ github.com/openshift/api/template/v1 github.com/openshift/api/unidling/v1alpha1 github.com/openshift/api/user github.com/openshift/api/user/v1 -# github.com/openshift/apiserver-library-go v0.0.0-20200723181026-dd21ec96ba0a +# github.com/openshift/apiserver-library-go v0.0.0-20200901140731-1236dc23c728 github.com/openshift/apiserver-library-go/pkg/admission/imagepolicy github.com/openshift/apiserver-library-go/pkg/admission/imagepolicy/apis/imagepolicy/v1 github.com/openshift/apiserver-library-go/pkg/admission/imagepolicy/apis/imagepolicy/validation @@ -672,7 +674,7 @@ github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/selinux github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/user github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/util github.com/openshift/apiserver-library-go/pkg/securitycontextconstraints/util/sort -# github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7 +# github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7 github.com/openshift/build-machinery-go github.com/openshift/build-machinery-go/make github.com/openshift/build-machinery-go/make/lib @@ -681,7 +683,7 @@ github.com/openshift/build-machinery-go/make/targets/golang github.com/openshift/build-machinery-go/make/targets/openshift github.com/openshift/build-machinery-go/make/targets/openshift/operator github.com/openshift/build-machinery-go/scripts -# github.com/openshift/client-go v0.0.0-20200722173614-5a1b0aaeff15 +# github.com/openshift/client-go v0.0.0-20200827190008-3062137373b5 github.com/openshift/client-go/apps/clientset/versioned github.com/openshift/client-go/apps/clientset/versioned/scheme github.com/openshift/client-go/apps/clientset/versioned/typed/apps/v1 @@ -747,7 +749,7 @@ github.com/openshift/client-go/user/informers/externalversions/internalinterface github.com/openshift/client-go/user/informers/externalversions/user github.com/openshift/client-go/user/informers/externalversions/user/v1 github.com/openshift/client-go/user/listers/user/v1 -# github.com/openshift/library-go v0.0.0-20200722204747-e3f2c82ff290 +# github.com/openshift/library-go v0.0.0-20200902112127-a4e32e339219 github.com/openshift/library-go/pkg/apiserver/admission/admissionrestconfig github.com/openshift/library-go/pkg/apiserver/admission/admissiontimeout github.com/openshift/library-go/pkg/apiserver/apiserverconfig @@ -1034,7 +1036,7 @@ go.uber.org/zap/internal/bufferpool go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore -# golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 => golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 +# golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 => golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish golang.org/x/crypto/cast5 @@ -1062,7 +1064,7 @@ golang.org/x/crypto/ssh/agent golang.org/x/crypto/ssh/internal/bcrypt_pbkdf golang.org/x/crypto/ssh/knownhosts golang.org/x/crypto/ssh/terminal -# golang.org/x/net v0.0.0-20200602114024-627f9648deb9 => golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 +# golang.org/x/net v0.0.0-20200707034311-ab3426394381 => golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 golang.org/x/net/bpf golang.org/x/net/context golang.org/x/net/context/ctxhttp @@ -1121,7 +1123,7 @@ golang.org/x/text/unicode/norm golang.org/x/text/width # golang.org/x/time v0.0.0-20191024005414-555d28b269f0 => golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/time/rate -# golang.org/x/tools v0.0.0-20200602230032-c00d67ef29d0 => golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7 +# golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 => golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7 golang.org/x/tools/container/intsets # google.golang.org/api v0.15.1 google.golang.org/api/compute/v0.alpha @@ -1271,7 +1273,7 @@ gopkg.in/tomb.v1 gopkg.in/warnings.v0 # gopkg.in/yaml.v2 v2.3.0 => gopkg.in/yaml.v2 v2.2.8 gopkg.in/yaml.v2 -# k8s.io/api v0.19.0-rc.2 => k8s.io/api v0.19.0-rc.2 +# k8s.io/api v0.19.0 => k8s.io/api v0.19.0-rc.2 k8s.io/api/admission/v1 k8s.io/api/admission/v1beta1 k8s.io/api/admissionregistration/v1 @@ -1316,7 +1318,7 @@ k8s.io/api/settings/v1alpha1 k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 -# k8s.io/apiextensions-apiserver v0.19.0-rc.2 => k8s.io/apiextensions-apiserver v0.19.0-rc.2 +# k8s.io/apiextensions-apiserver v0.19.0 => k8s.io/apiextensions-apiserver v0.19.0-rc.2 k8s.io/apiextensions-apiserver/pkg/apihelpers k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install @@ -1359,7 +1361,7 @@ k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition k8s.io/apiextensions-apiserver/test/integration k8s.io/apiextensions-apiserver/test/integration/fixtures -# k8s.io/apimachinery v0.19.0-rc.2 => k8s.io/apimachinery v0.19.0-rc.2 +# k8s.io/apimachinery v0.19.0 => k8s.io/apimachinery v0.19.0-rc.2 k8s.io/apimachinery/pkg/api/apitesting k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -1422,7 +1424,7 @@ k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/json k8s.io/apimachinery/third_party/forked/golang/netutil k8s.io/apimachinery/third_party/forked/golang/reflect -# k8s.io/apiserver v0.19.0-rc.2 => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20200826132615-f71a7ab366cf +# k8s.io/apiserver v0.19.0 => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20200916071455-b4ffb455315c k8s.io/apiserver/pkg/admission k8s.io/apiserver/pkg/admission/configuration k8s.io/apiserver/pkg/admission/initializer @@ -1512,6 +1514,7 @@ k8s.io/apiserver/pkg/storage k8s.io/apiserver/pkg/storage/cacher k8s.io/apiserver/pkg/storage/errors k8s.io/apiserver/pkg/storage/etcd3 +k8s.io/apiserver/pkg/storage/etcd3/etcd3retry k8s.io/apiserver/pkg/storage/etcd3/metrics k8s.io/apiserver/pkg/storage/etcd3/preflight k8s.io/apiserver/pkg/storage/etcd3/testing @@ -1564,7 +1567,7 @@ k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator k8s.io/cli-runtime/pkg/printers k8s.io/cli-runtime/pkg/resource -# k8s.io/client-go v0.19.0-rc.2 => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20200826132615-f71a7ab366cf +# k8s.io/client-go v0.19.0 => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20200916071455-b4ffb455315c k8s.io/client-go/discovery k8s.io/client-go/discovery/cached k8s.io/client-go/discovery/cached/disk @@ -1809,7 +1812,7 @@ k8s.io/client-go/util/jsonpath k8s.io/client-go/util/keyutil k8s.io/client-go/util/retry k8s.io/client-go/util/workqueue -# k8s.io/cloud-provider v0.19.0-rc.2 => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20200826132615-f71a7ab366cf +# k8s.io/cloud-provider v0.19.0-rc.2 => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20200916071455-b4ffb455315c k8s.io/cloud-provider k8s.io/cloud-provider/api k8s.io/cloud-provider/node/helpers @@ -1822,7 +1825,7 @@ k8s.io/cluster-bootstrap/token/api k8s.io/cluster-bootstrap/token/util k8s.io/cluster-bootstrap/util/secrets k8s.io/cluster-bootstrap/util/tokens -# k8s.io/component-base v0.19.0-rc.2 => k8s.io/component-base v0.19.0-rc.2 +# k8s.io/component-base v0.19.0 => k8s.io/component-base v0.19.0-rc.2 k8s.io/component-base/cli/flag k8s.io/component-base/cli/globalflag k8s.io/component-base/codec @@ -1850,9 +1853,9 @@ k8s.io/csi-translation-lib k8s.io/csi-translation-lib/plugins # k8s.io/klog v1.0.0 => k8s.io/klog v1.0.0 k8s.io/klog -# k8s.io/klog/v2 v2.2.0 +# k8s.io/klog/v2 v2.3.0 k8s.io/klog/v2 -# k8s.io/kube-aggregator v0.19.0-rc.2 => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20200826132615-f71a7ab366cf +# k8s.io/kube-aggregator v0.19.0 => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20200916071455-b4ffb455315c k8s.io/kube-aggregator/pkg/apis/apiregistration k8s.io/kube-aggregator/pkg/apis/apiregistration/install k8s.io/kube-aggregator/pkg/apis/apiregistration/v1 @@ -1880,7 +1883,7 @@ k8s.io/kube-aggregator/pkg/controllers/status k8s.io/kube-aggregator/pkg/registry/apiservice k8s.io/kube-aggregator/pkg/registry/apiservice/etcd k8s.io/kube-aggregator/pkg/registry/apiservice/rest -# k8s.io/kube-openapi v0.0.0-20200427153329-656914f816f9 +# k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 k8s.io/kube-openapi/pkg/aggregator k8s.io/kube-openapi/pkg/builder k8s.io/kube-openapi/pkg/common @@ -1921,7 +1924,7 @@ k8s.io/kubectl/pkg/validation k8s.io/kubelet/config/v1beta1 k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1 k8s.io/kubelet/pkg/apis/pluginregistration/v1 -# k8s.io/kubernetes v1.19.0-rc.2 => github.com/openshift/kubernetes v1.20.0-alpha.0.0.20200826132615-f71a7ab366cf +# k8s.io/kubernetes v1.19.0 => github.com/openshift/kubernetes v1.20.0-alpha.0.0.20200916071455-b4ffb455315c k8s.io/kubernetes/cmd/kube-apiserver/app k8s.io/kubernetes/cmd/kube-apiserver/app/options k8s.io/kubernetes/cmd/kube-proxy/app @@ -1980,7 +1983,6 @@ k8s.io/kubernetes/openshift-kube-apiserver/authorization/scopeauthorizer k8s.io/kubernetes/openshift-kube-apiserver/configdefault k8s.io/kubernetes/openshift-kube-apiserver/enablement k8s.io/kubernetes/openshift-kube-apiserver/openshiftkubeapiserver -k8s.io/kubernetes/pkg/api/endpoints k8s.io/kubernetes/pkg/api/legacyscheme k8s.io/kubernetes/pkg/api/persistentvolume k8s.io/kubernetes/pkg/api/persistentvolumeclaim @@ -2598,6 +2600,7 @@ k8s.io/kubernetes/test/e2e/framework/autoscaling k8s.io/kubernetes/test/e2e/framework/config k8s.io/kubernetes/test/e2e/framework/deployment k8s.io/kubernetes/test/e2e/framework/endpoints +k8s.io/kubernetes/test/e2e/framework/endpointslice k8s.io/kubernetes/test/e2e/framework/events k8s.io/kubernetes/test/e2e/framework/ginkgowrapper k8s.io/kubernetes/test/e2e/framework/gpu @@ -2671,7 +2674,7 @@ k8s.io/kubernetes/third_party/forked/gonum/graph k8s.io/kubernetes/third_party/forked/gonum/graph/internal/linear k8s.io/kubernetes/third_party/forked/gonum/graph/simple k8s.io/kubernetes/third_party/forked/gonum/graph/traverse -# k8s.io/legacy-cloud-providers v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/legacy-cloud-providers v0.0.0-20200826132615-f71a7ab366cf +# k8s.io/legacy-cloud-providers v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/legacy-cloud-providers v0.0.0-20200916071455-b4ffb455315c k8s.io/legacy-cloud-providers/aws k8s.io/legacy-cloud-providers/azure k8s.io/legacy-cloud-providers/azure/auth @@ -2725,7 +2728,7 @@ k8s.io/metrics/pkg/client/external_metrics # k8s.io/sample-apiserver v0.0.0 => k8s.io/sample-apiserver v0.19.0-rc.2 k8s.io/sample-apiserver/pkg/apis/wardle k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1 -# k8s.io/utils v0.0.0-20200720150651-0bdb4ca86cbc => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 +# k8s.io/utils v0.0.0-20200729134348-d5654de09c73 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 k8s.io/utils/buffer k8s.io/utils/clock k8s.io/utils/exec @@ -2767,10 +2770,12 @@ sigs.k8s.io/kustomize/pkg/transformers/config sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig sigs.k8s.io/kustomize/pkg/types # sigs.k8s.io/structured-merge-diff/v3 v3.0.1-0.20200706213357-43c19bbb7fba => sigs.k8s.io/structured-merge-diff/v3 v3.0.0 -sigs.k8s.io/structured-merge-diff/v3/fieldpath -sigs.k8s.io/structured-merge-diff/v3/merge -sigs.k8s.io/structured-merge-diff/v3/schema -sigs.k8s.io/structured-merge-diff/v3/typed sigs.k8s.io/structured-merge-diff/v3/value +# sigs.k8s.io/structured-merge-diff/v4 v4.0.1 +sigs.k8s.io/structured-merge-diff/v4/fieldpath +sigs.k8s.io/structured-merge-diff/v4/merge +sigs.k8s.io/structured-merge-diff/v4/schema +sigs.k8s.io/structured-merge-diff/v4/typed +sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 => sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/LICENSE b/vendor/sigs.k8s.io/structured-merge-diff/v4/LICENSE new file mode 100644 index 000000000000..8dada3edaf50 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/doc.go similarity index 100% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/doc.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/doc.go diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/element.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/element.go similarity index 99% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/element.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/element.go index 1b4872b86c20..1578f64c0486 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/element.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/element.go @@ -21,7 +21,7 @@ import ( "sort" "strings" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/value" ) // PathElement describes how to select a child field given a containing object. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/fromvalue.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/fromvalue.go similarity index 98% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/fromvalue.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/fromvalue.go index 36b2d4a916e5..20775ee0223c 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/fromvalue.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/fromvalue.go @@ -17,7 +17,7 @@ limitations under the License. package fieldpath import ( - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/value" ) // SetFromValue creates a set containing every leaf field mentioned in v. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/managers.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/managers.go similarity index 100% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/managers.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/managers.go diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/path.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/path.go similarity index 98% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/path.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/path.go index cc7fb9c67596..0413130bd17f 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/path.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/path.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/value" ) // Path describes how to select a potentially deeply-nested child field given a diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/pathelementmap.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/pathelementmap.go similarity index 98% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/pathelementmap.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/pathelementmap.go index fc8a1ff3fdd3..9b14ca581b01 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/pathelementmap.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/pathelementmap.go @@ -19,7 +19,7 @@ package fieldpath import ( "sort" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/value" ) // PathElementValueMap is a map from PathElement to value.Value. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/serialize-pe.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize-pe.go similarity index 99% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/serialize-pe.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize-pe.go index fcb6b2fc967a..cb18e7b1ca99 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/serialize-pe.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize-pe.go @@ -24,7 +24,7 @@ import ( "strings" jsoniter "github.com/json-iterator/go" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/value" ) var ErrUnknownPathElementType = errors.New("unknown path element type") diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/serialize.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize.go similarity index 100% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/serialize.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/serialize.go diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/set.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/set.go similarity index 83% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/set.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/set.go index f280a2fc76ae..029c2b6003ed 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/fieldpath/set.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath/set.go @@ -94,6 +94,22 @@ func (s *Set) Difference(s2 *Set) *Set { } } +// RecursiveDifference returns a Set containing elements which: +// * appear in s +// * do not appear in s2 +// +// Compared to a regular difference, +// this removes every field **and its children** from s that is contained in s2. +// +// For example, with s containing `a.b.c` and s2 containing `a.b`, +// a RecursiveDifference will result in `a`, as the entire node `a.b` gets removed. +func (s *Set) RecursiveDifference(s2 *Set) *Set { + return &Set{ + Members: *s.Members.Difference(&s2.Members), + Children: *s.Children.RecursiveDifference(s2), + } +} + // Size returns the number of members of the set. func (s *Set) Size() int { return s.Members.Size() + s.Children.Size() @@ -333,6 +349,48 @@ func (s *SetNodeMap) Difference(s2 *Set) *SetNodeMap { return out } +// RecursiveDifference returns a SetNodeMap with members that appear in s but not in s2. +// +// Compared to a regular difference, +// this removes every field **and its children** from s that is contained in s2. +// +// For example, with s containing `a.b.c` and s2 containing `a.b`, +// a RecursiveDifference will result in `a`, as the entire node `a.b` gets removed. +func (s *SetNodeMap) RecursiveDifference(s2 *Set) *SetNodeMap { + out := &SetNodeMap{} + + i, j := 0, 0 + for i < len(s.members) && j < len(s2.Children.members) { + if s.members[i].pathElement.Less(s2.Children.members[j].pathElement) { + if !s2.Members.Has(s.members[i].pathElement) { + out.members = append(out.members, setNode{pathElement: s.members[i].pathElement, set: s.members[i].set}) + } + i++ + } else { + if !s2.Children.members[j].pathElement.Less(s.members[i].pathElement) { + if !s2.Members.Has(s.members[i].pathElement) { + diff := s.members[i].set.RecursiveDifference(s2.Children.members[j].set) + if !diff.Empty() { + out.members = append(out.members, setNode{pathElement: s.members[i].pathElement, set: diff}) + } + } + i++ + } + j++ + } + } + + if i < len(s.members) { + for _, c := range s.members[i:] { + if !s2.Members.Has(c.pathElement) { + out.members = append(out.members, c) + } + } + } + + return out +} + // Iterate calls f for each PathElement in the set. func (s *SetNodeMap) Iterate(f func(PathElement)) { for _, n := range s.members { diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/merge/conflict.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go similarity index 90% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/merge/conflict.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go index 2dbd274ee654..75a492d8ea85 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/merge/conflict.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go @@ -21,7 +21,7 @@ import ( "sort" "strings" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) // Conflict is a conflict on a specific field with the current manager of @@ -95,6 +95,15 @@ func (c Conflicts) Equals(c2 Conflicts) bool { return true } +// ToSet aggregates conflicts for all managers into a single Set. +func (c Conflicts) ToSet() *fieldpath.Set { + set := fieldpath.NewSet() + for _, conflict := range []Conflict(c) { + set.Insert(conflict.Path) + } + return set +} + // ConflictsFromManagers creates a list of conflicts given Managers sets. func ConflictsFromManagers(sets fieldpath.ManagedFields) Conflicts { conflicts := []Conflict{} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/merge/update.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go similarity index 87% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/merge/update.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go index 3c2a46901a77..e648d8a270f7 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/merge/update.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go @@ -16,8 +16,8 @@ package merge import ( "fmt" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/typed" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/typed" ) // Converter is an interface to the conversion logic. The converter @@ -30,7 +30,8 @@ type Converter interface { // Updater is the object used to compute updated FieldSets and also // merge the object on Apply. type Updater struct { - Converter Converter + Converter Converter + IgnoredFields map[fieldpath.APIVersion]*fieldpath.Set enableUnions bool } @@ -50,7 +51,7 @@ func (s *Updater) update(oldObject, newObject *typed.TypedValue, version fieldpa } versions := map[fieldpath.APIVersion]*typed.Comparison{ - version: compare, + version: compare.ExcludeFields(s.IgnoredFields[version]), } for manager, managerSet := range managers { @@ -80,7 +81,7 @@ func (s *Updater) update(oldObject, newObject *typed.TypedValue, version fieldpa if err != nil { return nil, nil, fmt.Errorf("failed to compare objects: %v", err) } - versions[managerSet.APIVersion()] = compare + versions[managerSet.APIVersion()] = compare.ExcludeFields(s.IgnoredFields[managerSet.APIVersion()]) } conflictSet := managerSet.Set().Intersection(compare.Modified.Union(compare.Added)) @@ -135,8 +136,13 @@ func (s *Updater) Update(liveObject, newObject *typed.TypedValue, version fieldp if _, ok := managers[manager]; !ok { managers[manager] = fieldpath.NewVersionedSet(fieldpath.NewSet(), version, false) } + + ignored := s.IgnoredFields[version] + if ignored == nil { + ignored = fieldpath.NewSet() + } managers[manager] = fieldpath.NewVersionedSet( - managers[manager].Set().Union(compare.Modified).Union(compare.Added).Difference(compare.Removed), + managers[manager].Set().Union(compare.Modified).Union(compare.Added).Difference(compare.Removed).RecursiveDifference(ignored), version, false, ) @@ -174,6 +180,15 @@ func (s *Updater) Apply(liveObject, configObject *typed.TypedValue, version fiel if err != nil { return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to get field set: %v", err) } + + ignored := s.IgnoredFields[version] + if ignored != nil { + set = set.RecursiveDifference(ignored) + // TODO: is this correct. If we don't remove from lastSet pruning might remove the fields? + if lastSet != nil { + lastSet.Set().RecursiveDifference(ignored) + } + } managers[manager] = fieldpath.NewVersionedSet(set, version, true) newObject, err = s.prune(newObject, managers, manager, lastSet) if err != nil { @@ -197,7 +212,7 @@ func shallowCopyManagers(managers fieldpath.ManagedFields) fieldpath.ManagedFiel return newManagers } -// prune will remove a list or map item, iff: +// prune will remove a field, list or map item, iff: // * applyingManager applied it last time // * applyingManager didn't apply it this time // * no other applier claims to manage it @@ -225,18 +240,16 @@ func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFiel return s.Converter.Convert(pruned, managers[applyingManager].APIVersion()) } -// addBackOwnedItems adds back any list and map items that were removed by prune, -// but other appliers (or the current applier's new config) claim to own. +// addBackOwnedItems adds back any fields, list and map items that were removed by prune, +// but other appliers or updaters (or the current applier's new config) claim to own. func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFields fieldpath.ManagedFields, applyingManager string) (*typed.TypedValue, error) { var err error managedAtVersion := map[fieldpath.APIVersion]*fieldpath.Set{} for _, managerSet := range managedFields { - if managerSet.Applied() { - if _, ok := managedAtVersion[managerSet.APIVersion()]; !ok { - managedAtVersion[managerSet.APIVersion()] = fieldpath.NewSet() - } - managedAtVersion[managerSet.APIVersion()] = managedAtVersion[managerSet.APIVersion()].Union(managerSet.Set()) + if _, ok := managedAtVersion[managerSet.APIVersion()]; !ok { + managedAtVersion[managerSet.APIVersion()] = fieldpath.NewSet() } + managedAtVersion[managerSet.APIVersion()] = managedAtVersion[managerSet.APIVersion()].Union(managerSet.Set()) } for version, managed := range managedAtVersion { merged, err = s.Converter.Convert(merged, version) @@ -266,9 +279,9 @@ func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFie return pruned, nil } -// addBackDanglingItems makes sure that the only items removed by prune are items that were -// previously owned by the currently applying manager. This will add back unowned items and items -// which are owned by Updaters that shouldn't be removed. +// addBackDanglingItems makes sure that the fields list and map items removed by prune were +// previously owned by the currently applying manager. This will add back fields list and map items +// that are unowned or that are owned by Updaters and shouldn't be removed. func (s *Updater) addBackDanglingItems(merged, pruned *typed.TypedValue, lastSet fieldpath.VersionedSet) (*typed.TypedValue, error) { convertedPruned, err := s.Converter.Convert(pruned, lastSet.APIVersion()) if err != nil { diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/schema/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/doc.go similarity index 100% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/schema/doc.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/schema/doc.go diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/schema/elements.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go similarity index 100% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/schema/elements.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/schema/equals.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go similarity index 100% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/schema/equals.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/schema/schemaschema.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go similarity index 100% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/schema/schemaschema.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/doc.go similarity index 100% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/doc.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/doc.go diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/helpers.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go similarity index 97% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/helpers.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go index 0834f4d32756..9b6845e8da61 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/helpers.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go @@ -21,9 +21,9 @@ import ( "fmt" "strings" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/schema" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/value" ) // ValidationError reports an error about a particular field diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/merge.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go similarity index 98% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/merge.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go index e9573cc2310c..5112e2536f5b 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/merge.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go @@ -19,9 +19,9 @@ package typed import ( "math" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/schema" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/value" ) type mergingWalker struct { diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/parser.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/parser.go similarity index 98% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/parser.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/parser.go index 845fdfe4ec04..3949a78fc670 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/parser.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/parser.go @@ -20,8 +20,8 @@ import ( "fmt" yaml "gopkg.in/yaml.v2" - "sigs.k8s.io/structured-merge-diff/v3/schema" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/value" ) // YAMLObject is an object encoded in YAML. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/remove.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/remove.go similarity index 93% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/remove.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/remove.go index f30e02a618fc..a28119530167 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/remove.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/remove.go @@ -14,9 +14,9 @@ limitations under the License. package typed import ( - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/schema" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/value" ) type removingWalker struct { @@ -95,10 +95,9 @@ func (w *removingWalker) doMap(t *schema.Map) ValidationErrors { fieldType := t.ElementType if ft, ok := fieldTypes[k]; ok { fieldType = ft - } else { - if w.toRemove.Has(path) { - return true - } + } + if w.toRemove.Has(path) { + return true } if subset := w.toRemove.WithPrefix(pe); !subset.Empty() { val = removeItemsWithSchema(val, subset, w.schema, fieldType) diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/tofieldset.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/tofieldset.go similarity index 96% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/tofieldset.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/tofieldset.go index b3c4ff00217f..0662d0f0a808 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/tofieldset.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/tofieldset.go @@ -19,9 +19,9 @@ package typed import ( "sync" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/schema" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/value" ) var tPool = sync.Pool{ diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/typed.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go similarity index 93% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/typed.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go index 4aa9a238719a..1a99159a6eb3 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/typed.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go @@ -21,9 +21,9 @@ import ( "strings" "sync" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/schema" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/value" ) // AsTyped accepts a value and a type and returns a TypedValue. 'v' must have @@ -61,6 +61,11 @@ type TypedValue struct { schema *schema.Schema } +// TypeRef is the type of the value. +func (tv TypedValue) TypeRef() schema.TypeRef { + return tv.typeRef +} + // AsValue removes the type from the TypedValue and only keeps the value. func (tv TypedValue) AsValue() value.Value { return tv.value @@ -291,3 +296,15 @@ func (c *Comparison) String() string { } return bld.String() } + +// ExcludeFields fields from the compare recursively removes the fields +// from the entire comparison +func (c *Comparison) ExcludeFields(fields *fieldpath.Set) *Comparison { + if fields == nil || fields.Empty() { + return c + } + c.Removed = c.Removed.RecursiveDifference(fields) + c.Modified = c.Modified.RecursiveDifference(fields) + c.Added = c.Added.RecursiveDifference(fields) + return c +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/union.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/union.go similarity index 98% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/union.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/union.go index 26526cb87545..1fa5d88ae63c 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/union.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/union.go @@ -20,8 +20,8 @@ import ( "fmt" "strings" - "sigs.k8s.io/structured-merge-diff/v3/schema" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/value" ) func normalizeUnions(w *mergingWalker) error { diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/validate.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/validate.go similarity index 97% rename from vendor/sigs.k8s.io/structured-merge-diff/v3/typed/validate.go rename to vendor/sigs.k8s.io/structured-merge-diff/v4/typed/validate.go index 5c5a1cb64e0f..a2f8f4eff12a 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v3/typed/validate.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/validate.go @@ -19,9 +19,9 @@ package typed import ( "sync" - "sigs.k8s.io/structured-merge-diff/v3/fieldpath" - "sigs.k8s.io/structured-merge-diff/v3/schema" - "sigs.k8s.io/structured-merge-diff/v3/value" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/value" ) var vPool = sync.Pool{ diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/allocator.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/allocator.go new file mode 100644 index 000000000000..f70cd41674bb --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/allocator.go @@ -0,0 +1,203 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +// Allocator provides a value object allocation strategy. +// Value objects can be allocated by passing an allocator to the "Using" +// receiver functions on the value interfaces, e.g. Map.ZipUsing(allocator, ...). +// Value objects returned from "Using" functions should be given back to the allocator +// once longer needed by calling Allocator.Free(Value). +type Allocator interface { + // Free gives the allocator back any value objects returned by the "Using" + // receiver functions on the value interfaces. + // interface{} may be any of: Value, Map, List or Range. + Free(interface{}) + + // The unexported functions are for "Using" receiver functions of the value types + // to request what they need from the allocator. + allocValueUnstructured() *valueUnstructured + allocListUnstructuredRange() *listUnstructuredRange + allocValueReflect() *valueReflect + allocMapReflect() *mapReflect + allocStructReflect() *structReflect + allocListReflect() *listReflect + allocListReflectRange() *listReflectRange +} + +// HeapAllocator simply allocates objects to the heap. It is the default +// allocator used receiver functions on the value interfaces that do not accept +// an allocator and should be used whenever allocating objects that will not +// be given back to an allocator by calling Allocator.Free(Value). +var HeapAllocator = &heapAllocator{} + +type heapAllocator struct{} + +func (p *heapAllocator) allocValueUnstructured() *valueUnstructured { + return &valueUnstructured{} +} + +func (p *heapAllocator) allocListUnstructuredRange() *listUnstructuredRange { + return &listUnstructuredRange{vv: &valueUnstructured{}} +} + +func (p *heapAllocator) allocValueReflect() *valueReflect { + return &valueReflect{} +} + +func (p *heapAllocator) allocStructReflect() *structReflect { + return &structReflect{} +} + +func (p *heapAllocator) allocMapReflect() *mapReflect { + return &mapReflect{} +} + +func (p *heapAllocator) allocListReflect() *listReflect { + return &listReflect{} +} + +func (p *heapAllocator) allocListReflectRange() *listReflectRange { + return &listReflectRange{vr: &valueReflect{}} +} + +func (p *heapAllocator) Free(_ interface{}) {} + +// NewFreelistAllocator creates freelist based allocator. +// This allocator provides fast allocation and freeing of short lived value objects. +// +// The freelists are bounded in size by freelistMaxSize. If more than this amount of value objects is +// allocated at once, the excess will be returned to the heap for garbage collection when freed. +// +// This allocator is unsafe and must not be accessed concurrently by goroutines. +// +// This allocator works well for traversal of value data trees. Typical usage is to acquire +// a freelist at the beginning of the traversal and use it through out +// for all temporary value access. +func NewFreelistAllocator() Allocator { + return &freelistAllocator{ + valueUnstructured: &freelist{new: func() interface{} { + return &valueUnstructured{} + }}, + listUnstructuredRange: &freelist{new: func() interface{} { + return &listUnstructuredRange{vv: &valueUnstructured{}} + }}, + valueReflect: &freelist{new: func() interface{} { + return &valueReflect{} + }}, + mapReflect: &freelist{new: func() interface{} { + return &mapReflect{} + }}, + structReflect: &freelist{new: func() interface{} { + return &structReflect{} + }}, + listReflect: &freelist{new: func() interface{} { + return &listReflect{} + }}, + listReflectRange: &freelist{new: func() interface{} { + return &listReflectRange{vr: &valueReflect{}} + }}, + } +} + +// Bound memory usage of freelists. This prevents the processing of very large lists from leaking memory. +// This limit is large enough for endpoints objects containing 1000 IP address entries. Freed objects +// that don't fit into the freelist are orphaned on the heap to be garbage collected. +const freelistMaxSize = 1000 + +type freelistAllocator struct { + valueUnstructured *freelist + listUnstructuredRange *freelist + valueReflect *freelist + mapReflect *freelist + structReflect *freelist + listReflect *freelist + listReflectRange *freelist +} + +type freelist struct { + list []interface{} + new func() interface{} +} + +func (f *freelist) allocate() interface{} { + var w2 interface{} + if n := len(f.list); n > 0 { + w2, f.list = f.list[n-1], f.list[:n-1] + } else { + w2 = f.new() + } + return w2 +} + +func (f *freelist) free(v interface{}) { + if len(f.list) < freelistMaxSize { + f.list = append(f.list, v) + } +} + +func (w *freelistAllocator) Free(value interface{}) { + switch v := value.(type) { + case *valueUnstructured: + v.Value = nil // don't hold references to unstructured objects + w.valueUnstructured.free(v) + case *listUnstructuredRange: + v.vv.Value = nil // don't hold references to unstructured objects + w.listUnstructuredRange.free(v) + case *valueReflect: + v.ParentMapKey = nil + v.ParentMap = nil + w.valueReflect.free(v) + case *mapReflect: + w.mapReflect.free(v) + case *structReflect: + w.structReflect.free(v) + case *listReflect: + w.listReflect.free(v) + case *listReflectRange: + v.vr.ParentMapKey = nil + v.vr.ParentMap = nil + w.listReflectRange.free(v) + } +} + +func (w *freelistAllocator) allocValueUnstructured() *valueUnstructured { + return w.valueUnstructured.allocate().(*valueUnstructured) +} + +func (w *freelistAllocator) allocListUnstructuredRange() *listUnstructuredRange { + return w.listUnstructuredRange.allocate().(*listUnstructuredRange) +} + +func (w *freelistAllocator) allocValueReflect() *valueReflect { + return w.valueReflect.allocate().(*valueReflect) +} + +func (w *freelistAllocator) allocStructReflect() *structReflect { + return w.structReflect.allocate().(*structReflect) +} + +func (w *freelistAllocator) allocMapReflect() *mapReflect { + return w.mapReflect.allocate().(*mapReflect) +} + +func (w *freelistAllocator) allocListReflect() *listReflect { + return w.listReflect.allocate().(*listReflect) +} + +func (w *freelistAllocator) allocListReflectRange() *listReflectRange { + return w.listReflectRange.allocate().(*listReflectRange) +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/doc.go new file mode 100644 index 000000000000..84d7f0f3fc23 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package value defines types for an in-memory representation of yaml or json +// objects, organized for convenient comparison with a schema (as defined by +// the sibling schema package). Functions for reading and writing the objects +// are also provided. +package value diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/fields.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/fields.go new file mode 100644 index 000000000000..be3c672494ee --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/fields.go @@ -0,0 +1,97 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "sort" + "strings" +) + +// Field is an individual key-value pair. +type Field struct { + Name string + Value Value +} + +// FieldList is a list of key-value pairs. Each field is expected to +// have a different name. +type FieldList []Field + +// Sort sorts the field list by Name. +func (f FieldList) Sort() { + if len(f) < 2 { + return + } + if len(f) == 2 { + if f[1].Name < f[0].Name { + f[0], f[1] = f[1], f[0] + } + return + } + sort.SliceStable(f, func(i, j int) bool { + return f[i].Name < f[j].Name + }) +} + +// Less compares two lists lexically. +func (f FieldList) Less(rhs FieldList) bool { + return f.Compare(rhs) == -1 +} + +// Compare compares two lists lexically. The result will be 0 if f==rhs, -1 +// if f < rhs, and +1 if f > rhs. +func (f FieldList) Compare(rhs FieldList) int { + i := 0 + for { + if i >= len(f) && i >= len(rhs) { + // Maps are the same length and all items are equal. + return 0 + } + if i >= len(f) { + // F is shorter. + return -1 + } + if i >= len(rhs) { + // RHS is shorter. + return 1 + } + if c := strings.Compare(f[i].Name, rhs[i].Name); c != 0 { + return c + } + if c := Compare(f[i].Value, rhs[i].Value); c != 0 { + return c + } + // The items are equal; continue. + i++ + } +} + +// Equals returns true if the two fieldslist are equals, false otherwise. +func (f FieldList) Equals(rhs FieldList) bool { + if len(f) != len(rhs) { + return false + } + for i := range f { + if f[i].Name != rhs[i].Name { + return false + } + if !Equals(f[i].Value, rhs[i].Value) { + return false + } + } + return true +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/jsontagutil.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/jsontagutil.go new file mode 100644 index 000000000000..d4adb8fc9d25 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/jsontagutil.go @@ -0,0 +1,91 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "fmt" + "reflect" + "strings" +) + +// TODO: This implements the same functionality as https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go#L236 +// but is based on the highly efficient approach from https://golang.org/src/encoding/json/encode.go + +func lookupJsonTags(f reflect.StructField) (name string, omit bool, inline bool, omitempty bool) { + tag := f.Tag.Get("json") + if tag == "-" { + return "", true, false, false + } + name, opts := parseTag(tag) + if name == "" { + name = f.Name + } + return name, false, opts.Contains("inline"), opts.Contains("omitempty") +} + +func isZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflect.Chan, reflect.Func: + panic(fmt.Sprintf("unsupported type: %v", v.Type())) + } + return false +} + +type tagOptions string + +// parseTag splits a struct field's json tag into its name and +// comma-separated options. +func parseTag(tag string) (string, tagOptions) { + if idx := strings.Index(tag, ","); idx != -1 { + return tag[:idx], tagOptions(tag[idx+1:]) + } + return tag, tagOptions("") +} + +// Contains reports whether a comma-separated list of options +// contains a particular substr flag. substr must be surrounded by a +// string boundary or commas. +func (o tagOptions) Contains(optionName string) bool { + if len(o) == 0 { + return false + } + s := string(o) + for s != "" { + var next string + i := strings.Index(s, ",") + if i >= 0 { + s, next = s[:i], s[i+1:] + } + if s == optionName { + return true + } + s = next + } + return false +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/list.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/list.go new file mode 100644 index 000000000000..0748f18e82e7 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/list.go @@ -0,0 +1,139 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +// List represents a list object. +type List interface { + // Length returns how many items can be found in the map. + Length() int + // At returns the item at the given position in the map. It will + // panic if the index is out of range. + At(int) Value + // AtUsing uses the provided allocator and returns the item at the given + // position in the map. It will panic if the index is out of range. + // The returned Value should be given back to the Allocator when no longer needed + // by calling Allocator.Free(Value). + AtUsing(Allocator, int) Value + // Range returns a ListRange for iterating over the items in the list. + Range() ListRange + // RangeUsing uses the provided allocator and returns a ListRange for + // iterating over the items in the list. + // The returned Range should be given back to the Allocator when no longer needed + // by calling Allocator.Free(Value). + RangeUsing(Allocator) ListRange + // Equals compares the two lists, and return true if they are the same, false otherwise. + // Implementations can use ListEquals as a general implementation for this methods. + Equals(List) bool + // EqualsUsing uses the provided allocator and compares the two lists, and return true if + // they are the same, false otherwise. Implementations can use ListEqualsUsing as a general + // implementation for this methods. + EqualsUsing(Allocator, List) bool +} + +// ListRange represents a single iteration across the items of a list. +type ListRange interface { + // Next increments to the next item in the range, if there is one, and returns true, or returns false if there are no more items. + Next() bool + // Item returns the index and value of the current item in the range. or panics if there is no current item. + // For efficiency, Item may reuse the values returned by previous Item calls. Callers should be careful avoid holding + // pointers to the value returned by Item() that escape the iteration loop since they become invalid once either + // Item() or Allocator.Free() is called. + Item() (index int, value Value) +} + +var EmptyRange = &emptyRange{} + +type emptyRange struct{} + +func (_ *emptyRange) Next() bool { + return false +} + +func (_ *emptyRange) Item() (index int, value Value) { + panic("Item called on empty ListRange") +} + +// ListEquals compares two lists lexically. +// WARN: This is a naive implementation, calling lhs.Equals(rhs) is typically the most efficient. +func ListEquals(lhs, rhs List) bool { + return ListEqualsUsing(HeapAllocator, lhs, rhs) +} + +// ListEqualsUsing uses the provided allocator and compares two lists lexically. +// WARN: This is a naive implementation, calling lhs.EqualsUsing(allocator, rhs) is typically the most efficient. +func ListEqualsUsing(a Allocator, lhs, rhs List) bool { + if lhs.Length() != rhs.Length() { + return false + } + + lhsRange := lhs.RangeUsing(a) + defer a.Free(lhsRange) + rhsRange := rhs.RangeUsing(a) + defer a.Free(rhsRange) + + for lhsRange.Next() && rhsRange.Next() { + _, lv := lhsRange.Item() + _, rv := rhsRange.Item() + if !EqualsUsing(a, lv, rv) { + return false + } + } + return true +} + +// ListLess compares two lists lexically. +func ListLess(lhs, rhs List) bool { + return ListCompare(lhs, rhs) == -1 +} + +// ListCompare compares two lists lexically. The result will be 0 if l==rhs, -1 +// if l < rhs, and +1 if l > rhs. +func ListCompare(lhs, rhs List) int { + return ListCompareUsing(HeapAllocator, lhs, rhs) +} + +// ListCompareUsing uses the provided allocator and compares two lists lexically. The result will be 0 if l==rhs, -1 +// if l < rhs, and +1 if l > rhs. +func ListCompareUsing(a Allocator, lhs, rhs List) int { + lhsRange := lhs.RangeUsing(a) + defer a.Free(lhsRange) + rhsRange := rhs.RangeUsing(a) + defer a.Free(rhsRange) + + for { + lhsOk := lhsRange.Next() + rhsOk := rhsRange.Next() + if !lhsOk && !rhsOk { + // Lists are the same length and all items are equal. + return 0 + } + if !lhsOk { + // LHS is shorter. + return -1 + } + if !rhsOk { + // RHS is shorter. + return 1 + } + _, lv := lhsRange.Item() + _, rv := rhsRange.Item() + if c := CompareUsing(a, lv, rv); c != 0 { + return c + } + // The items are equal; continue. + } +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/listreflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/listreflect.go new file mode 100644 index 000000000000..197d4c921d4a --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/listreflect.go @@ -0,0 +1,98 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "reflect" +) + +type listReflect struct { + Value reflect.Value +} + +func (r listReflect) Length() int { + val := r.Value + return val.Len() +} + +func (r listReflect) At(i int) Value { + val := r.Value + return mustWrapValueReflect(val.Index(i), nil, nil) +} + +func (r listReflect) AtUsing(a Allocator, i int) Value { + val := r.Value + return a.allocValueReflect().mustReuse(val.Index(i), nil, nil, nil) +} + +func (r listReflect) Unstructured() interface{} { + l := r.Length() + result := make([]interface{}, l) + for i := 0; i < l; i++ { + result[i] = r.At(i).Unstructured() + } + return result +} + +func (r listReflect) Range() ListRange { + return r.RangeUsing(HeapAllocator) +} + +func (r listReflect) RangeUsing(a Allocator) ListRange { + length := r.Value.Len() + if length == 0 { + return EmptyRange + } + rr := a.allocListReflectRange() + rr.list = r.Value + rr.i = -1 + rr.entry = TypeReflectEntryOf(r.Value.Type().Elem()) + return rr +} + +func (r listReflect) Equals(other List) bool { + return r.EqualsUsing(HeapAllocator, other) +} +func (r listReflect) EqualsUsing(a Allocator, other List) bool { + if otherReflectList, ok := other.(*listReflect); ok { + return reflect.DeepEqual(r.Value.Interface(), otherReflectList.Value.Interface()) + } + return ListEqualsUsing(a, &r, other) +} + +type listReflectRange struct { + list reflect.Value + vr *valueReflect + i int + entry *TypeReflectCacheEntry +} + +func (r *listReflectRange) Next() bool { + r.i += 1 + return r.i < r.list.Len() +} + +func (r *listReflectRange) Item() (index int, value Value) { + if r.i < 0 { + panic("Item() called before first calling Next()") + } + if r.i >= r.list.Len() { + panic("Item() called on ListRange with no more items") + } + v := r.list.Index(r.i) + return r.i, r.vr.mustReuse(v, r.entry, nil, nil) +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/listunstructured.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/listunstructured.go new file mode 100644 index 000000000000..64cd8e7c0c4f --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/listunstructured.go @@ -0,0 +1,74 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +type listUnstructured []interface{} + +func (l listUnstructured) Length() int { + return len(l) +} + +func (l listUnstructured) At(i int) Value { + return NewValueInterface(l[i]) +} + +func (l listUnstructured) AtUsing(a Allocator, i int) Value { + return a.allocValueUnstructured().reuse(l[i]) +} + +func (l listUnstructured) Equals(other List) bool { + return l.EqualsUsing(HeapAllocator, other) +} + +func (l listUnstructured) EqualsUsing(a Allocator, other List) bool { + return ListEqualsUsing(a, &l, other) +} + +func (l listUnstructured) Range() ListRange { + return l.RangeUsing(HeapAllocator) +} + +func (l listUnstructured) RangeUsing(a Allocator) ListRange { + if len(l) == 0 { + return EmptyRange + } + r := a.allocListUnstructuredRange() + r.list = l + r.i = -1 + return r +} + +type listUnstructuredRange struct { + list listUnstructured + vv *valueUnstructured + i int +} + +func (r *listUnstructuredRange) Next() bool { + r.i += 1 + return r.i < len(r.list) +} + +func (r *listUnstructuredRange) Item() (index int, value Value) { + if r.i < 0 { + panic("Item() called before first calling Next()") + } + if r.i >= len(r.list) { + panic("Item() called on ListRange with no more items") + } + return r.i, r.vv.reuse(r.list[r.i]) +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/map.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/map.go new file mode 100644 index 000000000000..168b9fa082b3 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/map.go @@ -0,0 +1,270 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "sort" +) + +// Map represents a Map or go structure. +type Map interface { + // Set changes or set the value of the given key. + Set(key string, val Value) + // Get returns the value for the given key, if present, or (nil, false) otherwise. + Get(key string) (Value, bool) + // GetUsing uses the provided allocator and returns the value for the given key, + // if present, or (nil, false) otherwise. + // The returned Value should be given back to the Allocator when no longer needed + // by calling Allocator.Free(Value). + GetUsing(a Allocator, key string) (Value, bool) + // Has returns true if the key is present, or false otherwise. + Has(key string) bool + // Delete removes the key from the map. + Delete(key string) + // Equals compares the two maps, and return true if they are the same, false otherwise. + // Implementations can use MapEquals as a general implementation for this methods. + Equals(other Map) bool + // EqualsUsing uses the provided allocator and compares the two maps, and return true if + // they are the same, false otherwise. Implementations can use MapEqualsUsing as a general + // implementation for this methods. + EqualsUsing(a Allocator, other Map) bool + // Iterate runs the given function for each key/value in the + // map. Returning false in the closure prematurely stops the + // iteration. + Iterate(func(key string, value Value) bool) bool + // IterateUsing uses the provided allocator and runs the given function for each key/value + // in the map. Returning false in the closure prematurely stops the iteration. + IterateUsing(Allocator, func(key string, value Value) bool) bool + // Length returns the number of items in the map. + Length() int + // Empty returns true if the map is empty. + Empty() bool + // Zip iterates over the entries of two maps together. If both maps contain a value for a given key, fn is called + // with the values from both maps, otherwise it is called with the value of the map that contains the key and nil + // for the map that does not contain the key. Returning false in the closure prematurely stops the iteration. + Zip(other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool + // ZipUsing uses the provided allocator and iterates over the entries of two maps together. If both maps + // contain a value for a given key, fn is called with the values from both maps, otherwise it is called with + // the value of the map that contains the key and nil for the map that does not contain the key. Returning + // false in the closure prematurely stops the iteration. + ZipUsing(a Allocator, other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool +} + +// MapTraverseOrder defines the map traversal ordering available. +type MapTraverseOrder int + +const ( + // Unordered indicates that the map traversal has no ordering requirement. + Unordered = iota + // LexicalKeyOrder indicates that the map traversal is ordered by key, lexically. + LexicalKeyOrder +) + +// MapZip iterates over the entries of two maps together. If both maps contain a value for a given key, fn is called +// with the values from both maps, otherwise it is called with the value of the map that contains the key and nil +// for the other map. Returning false in the closure prematurely stops the iteration. +func MapZip(lhs, rhs Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + return MapZipUsing(HeapAllocator, lhs, rhs, order, fn) +} + +// MapZipUsing uses the provided allocator and iterates over the entries of two maps together. If both maps +// contain a value for a given key, fn is called with the values from both maps, otherwise it is called with +// the value of the map that contains the key and nil for the other map. Returning false in the closure +// prematurely stops the iteration. +func MapZipUsing(a Allocator, lhs, rhs Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + if lhs != nil { + return lhs.ZipUsing(a, rhs, order, fn) + } + if rhs != nil { + return rhs.ZipUsing(a, lhs, order, func(key string, rhs, lhs Value) bool { // arg positions of lhs and rhs deliberately swapped + return fn(key, lhs, rhs) + }) + } + return true +} + +// defaultMapZip provides a default implementation of Zip for implementations that do not need to provide +// their own optimized implementation. +func defaultMapZip(a Allocator, lhs, rhs Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + switch order { + case Unordered: + return unorderedMapZip(a, lhs, rhs, fn) + case LexicalKeyOrder: + return lexicalKeyOrderedMapZip(a, lhs, rhs, fn) + default: + panic("Unsupported map order") + } +} + +func unorderedMapZip(a Allocator, lhs, rhs Map, fn func(key string, lhs, rhs Value) bool) bool { + if (lhs == nil || lhs.Empty()) && (rhs == nil || rhs.Empty()) { + return true + } + + if lhs != nil { + ok := lhs.IterateUsing(a, func(key string, lhsValue Value) bool { + var rhsValue Value + if rhs != nil { + if item, ok := rhs.GetUsing(a, key); ok { + rhsValue = item + defer a.Free(rhsValue) + } + } + return fn(key, lhsValue, rhsValue) + }) + if !ok { + return false + } + } + if rhs != nil { + return rhs.IterateUsing(a, func(key string, rhsValue Value) bool { + if lhs == nil || !lhs.Has(key) { + return fn(key, nil, rhsValue) + } + return true + }) + } + return true +} + +func lexicalKeyOrderedMapZip(a Allocator, lhs, rhs Map, fn func(key string, lhs, rhs Value) bool) bool { + var lhsLength, rhsLength int + var orderedLength int // rough estimate of length of union of map keys + if lhs != nil { + lhsLength = lhs.Length() + orderedLength = lhsLength + } + if rhs != nil { + rhsLength = rhs.Length() + if rhsLength > orderedLength { + orderedLength = rhsLength + } + } + if lhsLength == 0 && rhsLength == 0 { + return true + } + + ordered := make([]string, 0, orderedLength) + if lhs != nil { + lhs.IterateUsing(a, func(key string, _ Value) bool { + ordered = append(ordered, key) + return true + }) + } + if rhs != nil { + rhs.IterateUsing(a, func(key string, _ Value) bool { + if lhs == nil || !lhs.Has(key) { + ordered = append(ordered, key) + } + return true + }) + } + sort.Strings(ordered) + for _, key := range ordered { + var litem, ritem Value + if lhs != nil { + litem, _ = lhs.GetUsing(a, key) + } + if rhs != nil { + ritem, _ = rhs.GetUsing(a, key) + } + ok := fn(key, litem, ritem) + if litem != nil { + a.Free(litem) + } + if ritem != nil { + a.Free(ritem) + } + if !ok { + return false + } + } + return true +} + +// MapLess compares two maps lexically. +func MapLess(lhs, rhs Map) bool { + return MapCompare(lhs, rhs) == -1 +} + +// MapCompare compares two maps lexically. +func MapCompare(lhs, rhs Map) int { + return MapCompareUsing(HeapAllocator, lhs, rhs) +} + +// MapCompareUsing uses the provided allocator and compares two maps lexically. +func MapCompareUsing(a Allocator, lhs, rhs Map) int { + c := 0 + var llength, rlength int + if lhs != nil { + llength = lhs.Length() + } + if rhs != nil { + rlength = rhs.Length() + } + if llength == 0 && rlength == 0 { + return 0 + } + i := 0 + MapZipUsing(a, lhs, rhs, LexicalKeyOrder, func(key string, lhs, rhs Value) bool { + switch { + case i == llength: + c = -1 + case i == rlength: + c = 1 + case lhs == nil: + c = 1 + case rhs == nil: + c = -1 + default: + c = CompareUsing(a, lhs, rhs) + } + i++ + return c == 0 + }) + return c +} + +// MapEquals returns true if lhs == rhs, false otherwise. This function +// acts on generic types and should not be used by callers, but can help +// implement Map.Equals. +// WARN: This is a naive implementation, calling lhs.Equals(rhs) is typically the most efficient. +func MapEquals(lhs, rhs Map) bool { + return MapEqualsUsing(HeapAllocator, lhs, rhs) +} + +// MapEqualsUsing uses the provided allocator and returns true if lhs == rhs, +// false otherwise. This function acts on generic types and should not be used +// by callers, but can help implement Map.Equals. +// WARN: This is a naive implementation, calling lhs.EqualsUsing(allocator, rhs) is typically the most efficient. +func MapEqualsUsing(a Allocator, lhs, rhs Map) bool { + if lhs == nil && rhs == nil { + return true + } + if lhs == nil || rhs == nil { + return false + } + if lhs.Length() != rhs.Length() { + return false + } + return MapZipUsing(a, lhs, rhs, Unordered, func(key string, lhs, rhs Value) bool { + if lhs == nil || rhs == nil { + return false + } + return EqualsUsing(a, lhs, rhs) + }) +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapreflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapreflect.go new file mode 100644 index 000000000000..dc8b8c72006c --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapreflect.go @@ -0,0 +1,209 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "reflect" +) + +type mapReflect struct { + valueReflect +} + +func (r mapReflect) Length() int { + val := r.Value + return val.Len() +} + +func (r mapReflect) Empty() bool { + val := r.Value + return val.Len() == 0 +} + +func (r mapReflect) Get(key string) (Value, bool) { + return r.GetUsing(HeapAllocator, key) +} + +func (r mapReflect) GetUsing(a Allocator, key string) (Value, bool) { + k, v, ok := r.get(key) + if !ok { + return nil, false + } + return a.allocValueReflect().mustReuse(v, nil, &r.Value, &k), true +} + +func (r mapReflect) get(k string) (key, value reflect.Value, ok bool) { + mapKey := r.toMapKey(k) + val := r.Value.MapIndex(mapKey) + return mapKey, val, val.IsValid() && val != reflect.Value{} +} + +func (r mapReflect) Has(key string) bool { + var val reflect.Value + val = r.Value.MapIndex(r.toMapKey(key)) + if !val.IsValid() { + return false + } + return val != reflect.Value{} +} + +func (r mapReflect) Set(key string, val Value) { + r.Value.SetMapIndex(r.toMapKey(key), reflect.ValueOf(val.Unstructured())) +} + +func (r mapReflect) Delete(key string) { + val := r.Value + val.SetMapIndex(r.toMapKey(key), reflect.Value{}) +} + +// TODO: Do we need to support types that implement json.Marshaler and are used as string keys? +func (r mapReflect) toMapKey(key string) reflect.Value { + val := r.Value + return reflect.ValueOf(key).Convert(val.Type().Key()) +} + +func (r mapReflect) Iterate(fn func(string, Value) bool) bool { + return r.IterateUsing(HeapAllocator, fn) +} + +func (r mapReflect) IterateUsing(a Allocator, fn func(string, Value) bool) bool { + if r.Value.Len() == 0 { + return true + } + v := a.allocValueReflect() + defer a.Free(v) + return eachMapEntry(r.Value, func(e *TypeReflectCacheEntry, key reflect.Value, value reflect.Value) bool { + return fn(key.String(), v.mustReuse(value, e, &r.Value, &key)) + }) +} + +func eachMapEntry(val reflect.Value, fn func(*TypeReflectCacheEntry, reflect.Value, reflect.Value) bool) bool { + iter := val.MapRange() + entry := TypeReflectEntryOf(val.Type().Elem()) + for iter.Next() { + next := iter.Value() + if !next.IsValid() { + continue + } + if !fn(entry, iter.Key(), next) { + return false + } + } + return true +} + +func (r mapReflect) Unstructured() interface{} { + result := make(map[string]interface{}, r.Length()) + r.Iterate(func(s string, value Value) bool { + result[s] = value.Unstructured() + return true + }) + return result +} + +func (r mapReflect) Equals(m Map) bool { + return r.EqualsUsing(HeapAllocator, m) +} + +func (r mapReflect) EqualsUsing(a Allocator, m Map) bool { + lhsLength := r.Length() + rhsLength := m.Length() + if lhsLength != rhsLength { + return false + } + if lhsLength == 0 { + return true + } + vr := a.allocValueReflect() + defer a.Free(vr) + entry := TypeReflectEntryOf(r.Value.Type().Elem()) + return m.Iterate(func(key string, value Value) bool { + _, lhsVal, ok := r.get(key) + if !ok { + return false + } + return Equals(vr.mustReuse(lhsVal, entry, nil, nil), value) + }) +} + +func (r mapReflect) Zip(other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + return r.ZipUsing(HeapAllocator, other, order, fn) +} + +func (r mapReflect) ZipUsing(a Allocator, other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + if otherMapReflect, ok := other.(*mapReflect); ok && order == Unordered { + return r.unorderedReflectZip(a, otherMapReflect, fn) + } + return defaultMapZip(a, &r, other, order, fn) +} + +// unorderedReflectZip provides an optimized unordered zip for mapReflect types. +func (r mapReflect) unorderedReflectZip(a Allocator, other *mapReflect, fn func(key string, lhs, rhs Value) bool) bool { + if r.Empty() && (other == nil || other.Empty()) { + return true + } + + lhs := r.Value + lhsEntry := TypeReflectEntryOf(lhs.Type().Elem()) + + // map lookup via reflection is expensive enough that it is better to keep track of visited keys + visited := map[string]struct{}{} + + vlhs, vrhs := a.allocValueReflect(), a.allocValueReflect() + defer a.Free(vlhs) + defer a.Free(vrhs) + + if other != nil { + rhs := other.Value + rhsEntry := TypeReflectEntryOf(rhs.Type().Elem()) + iter := rhs.MapRange() + + for iter.Next() { + key := iter.Key() + keyString := key.String() + next := iter.Value() + if !next.IsValid() { + continue + } + rhsVal := vrhs.mustReuse(next, rhsEntry, &rhs, &key) + visited[keyString] = struct{}{} + var lhsVal Value + if _, v, ok := r.get(keyString); ok { + lhsVal = vlhs.mustReuse(v, lhsEntry, &lhs, &key) + } + if !fn(keyString, lhsVal, rhsVal) { + return false + } + } + } + + iter := lhs.MapRange() + for iter.Next() { + key := iter.Key() + if _, ok := visited[key.String()]; ok { + continue + } + next := iter.Value() + if !next.IsValid() { + continue + } + if !fn(key.String(), vlhs.mustReuse(next, lhsEntry, &lhs, &key), nil) { + return false + } + } + return true +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapunstructured.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapunstructured.go new file mode 100644 index 000000000000..d8e208628def --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapunstructured.go @@ -0,0 +1,190 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +type mapUnstructuredInterface map[interface{}]interface{} + +func (m mapUnstructuredInterface) Set(key string, val Value) { + m[key] = val.Unstructured() +} + +func (m mapUnstructuredInterface) Get(key string) (Value, bool) { + return m.GetUsing(HeapAllocator, key) +} + +func (m mapUnstructuredInterface) GetUsing(a Allocator, key string) (Value, bool) { + if v, ok := m[key]; !ok { + return nil, false + } else { + return a.allocValueUnstructured().reuse(v), true + } +} + +func (m mapUnstructuredInterface) Has(key string) bool { + _, ok := m[key] + return ok +} + +func (m mapUnstructuredInterface) Delete(key string) { + delete(m, key) +} + +func (m mapUnstructuredInterface) Iterate(fn func(key string, value Value) bool) bool { + return m.IterateUsing(HeapAllocator, fn) +} + +func (m mapUnstructuredInterface) IterateUsing(a Allocator, fn func(key string, value Value) bool) bool { + if len(m) == 0 { + return true + } + vv := a.allocValueUnstructured() + defer a.Free(vv) + for k, v := range m { + if ks, ok := k.(string); !ok { + continue + } else { + if !fn(ks, vv.reuse(v)) { + return false + } + } + } + return true +} + +func (m mapUnstructuredInterface) Length() int { + return len(m) +} + +func (m mapUnstructuredInterface) Empty() bool { + return len(m) == 0 +} + +func (m mapUnstructuredInterface) Equals(other Map) bool { + return m.EqualsUsing(HeapAllocator, other) +} + +func (m mapUnstructuredInterface) EqualsUsing(a Allocator, other Map) bool { + lhsLength := m.Length() + rhsLength := other.Length() + if lhsLength != rhsLength { + return false + } + if lhsLength == 0 { + return true + } + vv := a.allocValueUnstructured() + defer a.Free(vv) + return other.Iterate(func(key string, value Value) bool { + lhsVal, ok := m[key] + if !ok { + return false + } + return Equals(vv.reuse(lhsVal), value) + }) +} + +func (m mapUnstructuredInterface) Zip(other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + return m.ZipUsing(HeapAllocator, other, order, fn) +} + +func (m mapUnstructuredInterface) ZipUsing(a Allocator, other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + return defaultMapZip(a, m, other, order, fn) +} + +type mapUnstructuredString map[string]interface{} + +func (m mapUnstructuredString) Set(key string, val Value) { + m[key] = val.Unstructured() +} + +func (m mapUnstructuredString) Get(key string) (Value, bool) { + return m.GetUsing(HeapAllocator, key) +} +func (m mapUnstructuredString) GetUsing(a Allocator, key string) (Value, bool) { + if v, ok := m[key]; !ok { + return nil, false + } else { + return a.allocValueUnstructured().reuse(v), true + } +} + +func (m mapUnstructuredString) Has(key string) bool { + _, ok := m[key] + return ok +} + +func (m mapUnstructuredString) Delete(key string) { + delete(m, key) +} + +func (m mapUnstructuredString) Iterate(fn func(key string, value Value) bool) bool { + return m.IterateUsing(HeapAllocator, fn) +} + +func (m mapUnstructuredString) IterateUsing(a Allocator, fn func(key string, value Value) bool) bool { + if len(m) == 0 { + return true + } + vv := a.allocValueUnstructured() + defer a.Free(vv) + for k, v := range m { + if !fn(k, vv.reuse(v)) { + return false + } + } + return true +} + +func (m mapUnstructuredString) Length() int { + return len(m) +} + +func (m mapUnstructuredString) Equals(other Map) bool { + return m.EqualsUsing(HeapAllocator, other) +} + +func (m mapUnstructuredString) EqualsUsing(a Allocator, other Map) bool { + lhsLength := m.Length() + rhsLength := other.Length() + if lhsLength != rhsLength { + return false + } + if lhsLength == 0 { + return true + } + vv := a.allocValueUnstructured() + defer a.Free(vv) + return other.Iterate(func(key string, value Value) bool { + lhsVal, ok := m[key] + if !ok { + return false + } + return Equals(vv.reuse(lhsVal), value) + }) +} + +func (m mapUnstructuredString) Zip(other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + return m.ZipUsing(HeapAllocator, other, order, fn) +} + +func (m mapUnstructuredString) ZipUsing(a Allocator, other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + return defaultMapZip(a, m, other, order, fn) +} + +func (m mapUnstructuredString) Empty() bool { + return len(m) == 0 +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/reflectcache.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/reflectcache.go new file mode 100644 index 000000000000..49e6dd1690e0 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/reflectcache.go @@ -0,0 +1,463 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "sort" + "sync" + "sync/atomic" +) + +// UnstructuredConverter defines how a type can be converted directly to unstructured. +// Types that implement json.Marshaler may also optionally implement this interface to provide a more +// direct and more efficient conversion. All types that choose to implement this interface must still +// implement this same conversion via json.Marshaler. +type UnstructuredConverter interface { + json.Marshaler // require that json.Marshaler is implemented + + // ToUnstructured returns the unstructured representation. + ToUnstructured() interface{} +} + +// TypeReflectCacheEntry keeps data gathered using reflection about how a type is converted to/from unstructured. +type TypeReflectCacheEntry struct { + isJsonMarshaler bool + ptrIsJsonMarshaler bool + isJsonUnmarshaler bool + ptrIsJsonUnmarshaler bool + isStringConvertable bool + ptrIsStringConvertable bool + + structFields map[string]*FieldCacheEntry + orderedStructFields []*FieldCacheEntry +} + +// FieldCacheEntry keeps data gathered using reflection about how the field of a struct is converted to/from +// unstructured. +type FieldCacheEntry struct { + // JsonName returns the name of the field according to the json tags on the struct field. + JsonName string + // isOmitEmpty is true if the field has the json 'omitempty' tag. + isOmitEmpty bool + // fieldPath is a list of field indices (see FieldByIndex) to lookup the value of + // a field in a reflect.Value struct. The field indices in the list form a path used + // to traverse through intermediary 'inline' fields. + fieldPath [][]int + + fieldType reflect.Type + TypeEntry *TypeReflectCacheEntry +} + +func (f *FieldCacheEntry) CanOmit(fieldVal reflect.Value) bool { + return f.isOmitEmpty && (safeIsNil(fieldVal) || isZero(fieldVal)) +} + +// GetUsing returns the field identified by this FieldCacheEntry from the provided struct. +func (f *FieldCacheEntry) GetFrom(structVal reflect.Value) reflect.Value { + // field might be nested within 'inline' structs + for _, elem := range f.fieldPath { + structVal = structVal.FieldByIndex(elem) + } + return structVal +} + +var marshalerType = reflect.TypeOf(new(json.Marshaler)).Elem() +var unmarshalerType = reflect.TypeOf(new(json.Unmarshaler)).Elem() +var unstructuredConvertableType = reflect.TypeOf(new(UnstructuredConverter)).Elem() +var defaultReflectCache = newReflectCache() + +// TypeReflectEntryOf returns the TypeReflectCacheEntry of the provided reflect.Type. +func TypeReflectEntryOf(t reflect.Type) *TypeReflectCacheEntry { + cm := defaultReflectCache.get() + if record, ok := cm[t]; ok { + return record + } + updates := reflectCacheMap{} + result := typeReflectEntryOf(cm, t, updates) + if len(updates) > 0 { + defaultReflectCache.update(updates) + } + return result +} + +// TypeReflectEntryOf returns all updates needed to add provided reflect.Type, and the types its fields transitively +// depend on, to the cache. +func typeReflectEntryOf(cm reflectCacheMap, t reflect.Type, updates reflectCacheMap) *TypeReflectCacheEntry { + if record, ok := cm[t]; ok { + return record + } + if record, ok := updates[t]; ok { + return record + } + typeEntry := &TypeReflectCacheEntry{ + isJsonMarshaler: t.Implements(marshalerType), + ptrIsJsonMarshaler: reflect.PtrTo(t).Implements(marshalerType), + isJsonUnmarshaler: reflect.PtrTo(t).Implements(unmarshalerType), + isStringConvertable: t.Implements(unstructuredConvertableType), + ptrIsStringConvertable: reflect.PtrTo(t).Implements(unstructuredConvertableType), + } + if t.Kind() == reflect.Struct { + fieldEntries := map[string]*FieldCacheEntry{} + buildStructCacheEntry(t, fieldEntries, nil) + typeEntry.structFields = fieldEntries + sortedByJsonName := make([]*FieldCacheEntry, len(fieldEntries)) + i := 0 + for _, entry := range fieldEntries { + sortedByJsonName[i] = entry + i++ + } + sort.Slice(sortedByJsonName, func(i, j int) bool { + return sortedByJsonName[i].JsonName < sortedByJsonName[j].JsonName + }) + typeEntry.orderedStructFields = sortedByJsonName + } + + // cyclic type references are allowed, so we must add the typeEntry to the updates map before resolving + // the field.typeEntry references, or creating them if they are not already in the cache + updates[t] = typeEntry + + for _, field := range typeEntry.structFields { + if field.TypeEntry == nil { + field.TypeEntry = typeReflectEntryOf(cm, field.fieldType, updates) + } + } + return typeEntry +} + +func buildStructCacheEntry(t reflect.Type, infos map[string]*FieldCacheEntry, fieldPath [][]int) { + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + jsonName, omit, isInline, isOmitempty := lookupJsonTags(field) + if omit { + continue + } + if isInline { + buildStructCacheEntry(field.Type, infos, append(fieldPath, field.Index)) + continue + } + info := &FieldCacheEntry{JsonName: jsonName, isOmitEmpty: isOmitempty, fieldPath: append(fieldPath, field.Index), fieldType: field.Type} + infos[jsonName] = info + } +} + +// Fields returns a map of JSON field name to FieldCacheEntry for structs, or nil for non-structs. +func (e TypeReflectCacheEntry) Fields() map[string]*FieldCacheEntry { + return e.structFields +} + +// Fields returns a map of JSON field name to FieldCacheEntry for structs, or nil for non-structs. +func (e TypeReflectCacheEntry) OrderedFields() []*FieldCacheEntry { + return e.orderedStructFields +} + +// CanConvertToUnstructured returns true if this TypeReflectCacheEntry can convert values of its type to unstructured. +func (e TypeReflectCacheEntry) CanConvertToUnstructured() bool { + return e.isJsonMarshaler || e.ptrIsJsonMarshaler || e.isStringConvertable || e.ptrIsStringConvertable +} + +// ToUnstructured converts the provided value to unstructured and returns it. +func (e TypeReflectCacheEntry) ToUnstructured(sv reflect.Value) (interface{}, error) { + // This is based on https://github.com/kubernetes/kubernetes/blob/82c9e5c814eb7acc6cc0a090c057294d0667ad66/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go#L505 + // and is intended to replace it. + + // Check if the object has a custom string converter and use it if available, since it is much more efficient + // than round tripping through json. + if converter, ok := e.getUnstructuredConverter(sv); ok { + return converter.ToUnstructured(), nil + } + // Check if the object has a custom JSON marshaller/unmarshaller. + if marshaler, ok := e.getJsonMarshaler(sv); ok { + if sv.Kind() == reflect.Ptr && sv.IsNil() { + // We're done - we don't need to store anything. + return nil, nil + } + + data, err := marshaler.MarshalJSON() + if err != nil { + return nil, err + } + switch { + case len(data) == 0: + return nil, fmt.Errorf("error decoding from json: empty value") + + case bytes.Equal(data, nullBytes): + // We're done - we don't need to store anything. + return nil, nil + + case bytes.Equal(data, trueBytes): + return true, nil + + case bytes.Equal(data, falseBytes): + return false, nil + + case data[0] == '"': + var result string + err := unmarshal(data, &result) + if err != nil { + return nil, fmt.Errorf("error decoding string from json: %v", err) + } + return result, nil + + case data[0] == '{': + result := make(map[string]interface{}) + err := unmarshal(data, &result) + if err != nil { + return nil, fmt.Errorf("error decoding object from json: %v", err) + } + return result, nil + + case data[0] == '[': + result := make([]interface{}, 0) + err := unmarshal(data, &result) + if err != nil { + return nil, fmt.Errorf("error decoding array from json: %v", err) + } + return result, nil + + default: + var ( + resultInt int64 + resultFloat float64 + err error + ) + if err = unmarshal(data, &resultInt); err == nil { + return resultInt, nil + } else if err = unmarshal(data, &resultFloat); err == nil { + return resultFloat, nil + } else { + return nil, fmt.Errorf("error decoding number from json: %v", err) + } + } + } + + return nil, fmt.Errorf("provided type cannot be converted: %v", sv.Type()) +} + +// CanConvertFromUnstructured returns true if this TypeReflectCacheEntry can convert objects of the type from unstructured. +func (e TypeReflectCacheEntry) CanConvertFromUnstructured() bool { + return e.isJsonUnmarshaler +} + +// FromUnstructured converts the provided source value from unstructured into the provided destination value. +func (e TypeReflectCacheEntry) FromUnstructured(sv, dv reflect.Value) error { + // TODO: this could be made much more efficient using direct conversions like + // UnstructuredConverter.ToUnstructured provides. + st := dv.Type() + data, err := json.Marshal(sv.Interface()) + if err != nil { + return fmt.Errorf("error encoding %s to json: %v", st.String(), err) + } + if unmarshaler, ok := e.getJsonUnmarshaler(dv); ok { + return unmarshaler.UnmarshalJSON(data) + } + return fmt.Errorf("unable to unmarshal %v into %v", sv.Type(), dv.Type()) +} + +var ( + nullBytes = []byte("null") + trueBytes = []byte("true") + falseBytes = []byte("false") +) + +func (e TypeReflectCacheEntry) getJsonMarshaler(v reflect.Value) (json.Marshaler, bool) { + if e.isJsonMarshaler { + return v.Interface().(json.Marshaler), true + } + if e.ptrIsJsonMarshaler { + // Check pointer receivers if v is not a pointer + if v.Kind() != reflect.Ptr && v.CanAddr() { + v = v.Addr() + return v.Interface().(json.Marshaler), true + } + } + return nil, false +} + +func (e TypeReflectCacheEntry) getJsonUnmarshaler(v reflect.Value) (json.Unmarshaler, bool) { + if !e.isJsonUnmarshaler { + return nil, false + } + return v.Addr().Interface().(json.Unmarshaler), true +} + +func (e TypeReflectCacheEntry) getUnstructuredConverter(v reflect.Value) (UnstructuredConverter, bool) { + if e.isStringConvertable { + return v.Interface().(UnstructuredConverter), true + } + if e.ptrIsStringConvertable { + // Check pointer receivers if v is not a pointer + if v.CanAddr() { + v = v.Addr() + return v.Interface().(UnstructuredConverter), true + } + } + return nil, false +} + +type typeReflectCache struct { + // use an atomic and copy-on-write since there are a fixed (typically very small) number of structs compiled into any + // go program using this cache + value atomic.Value + // mu is held by writers when performing load/modify/store operations on the cache, readers do not need to hold a + // read-lock since the atomic value is always read-only + mu sync.Mutex +} + +func newReflectCache() *typeReflectCache { + cache := &typeReflectCache{} + cache.value.Store(make(reflectCacheMap)) + return cache +} + +type reflectCacheMap map[reflect.Type]*TypeReflectCacheEntry + +// get returns the reflectCacheMap. +func (c *typeReflectCache) get() reflectCacheMap { + return c.value.Load().(reflectCacheMap) +} + +// update merges the provided updates into the cache. +func (c *typeReflectCache) update(updates reflectCacheMap) { + c.mu.Lock() + defer c.mu.Unlock() + + currentCacheMap := c.value.Load().(reflectCacheMap) + + hasNewEntries := false + for t := range updates { + if _, ok := currentCacheMap[t]; !ok { + hasNewEntries = true + break + } + } + if !hasNewEntries { + // Bail if the updates have been set while waiting for lock acquisition. + // This is safe since setting entries is idempotent. + return + } + + newCacheMap := make(reflectCacheMap, len(currentCacheMap)+len(updates)) + for k, v := range currentCacheMap { + newCacheMap[k] = v + } + for t, update := range updates { + newCacheMap[t] = update + } + c.value.Store(newCacheMap) +} + +// Below json Unmarshal is fromk8s.io/apimachinery/pkg/util/json +// to handle number conversions as expected by Kubernetes + +// limit recursive depth to prevent stack overflow errors +const maxDepth = 10000 + +// unmarshal unmarshals the given data +// If v is a *map[string]interface{}, numbers are converted to int64 or float64 +func unmarshal(data []byte, v interface{}) error { + switch v := v.(type) { + case *map[string]interface{}: + // Build a decoder from the given data + decoder := json.NewDecoder(bytes.NewBuffer(data)) + // Preserve numbers, rather than casting to float64 automatically + decoder.UseNumber() + // Run the decode + if err := decoder.Decode(v); err != nil { + return err + } + // If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64 + return convertMapNumbers(*v, 0) + + case *[]interface{}: + // Build a decoder from the given data + decoder := json.NewDecoder(bytes.NewBuffer(data)) + // Preserve numbers, rather than casting to float64 automatically + decoder.UseNumber() + // Run the decode + if err := decoder.Decode(v); err != nil { + return err + } + // If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64 + return convertSliceNumbers(*v, 0) + + default: + return json.Unmarshal(data, v) + } +} + +// convertMapNumbers traverses the map, converting any json.Number values to int64 or float64. +// values which are map[string]interface{} or []interface{} are recursively visited +func convertMapNumbers(m map[string]interface{}, depth int) error { + if depth > maxDepth { + return fmt.Errorf("exceeded max depth of %d", maxDepth) + } + + var err error + for k, v := range m { + switch v := v.(type) { + case json.Number: + m[k], err = convertNumber(v) + case map[string]interface{}: + err = convertMapNumbers(v, depth+1) + case []interface{}: + err = convertSliceNumbers(v, depth+1) + } + if err != nil { + return err + } + } + return nil +} + +// convertSliceNumbers traverses the slice, converting any json.Number values to int64 or float64. +// values which are map[string]interface{} or []interface{} are recursively visited +func convertSliceNumbers(s []interface{}, depth int) error { + if depth > maxDepth { + return fmt.Errorf("exceeded max depth of %d", maxDepth) + } + + var err error + for i, v := range s { + switch v := v.(type) { + case json.Number: + s[i], err = convertNumber(v) + case map[string]interface{}: + err = convertMapNumbers(v, depth+1) + case []interface{}: + err = convertSliceNumbers(v, depth+1) + } + if err != nil { + return err + } + } + return nil +} + +// convertNumber converts a json.Number to an int64 or float64, or returns an error +func convertNumber(n json.Number) (interface{}, error) { + // Attempt to convert to an int64 first + if i, err := n.Int64(); err == nil { + return i, nil + } + // Return a float64 (default json.Decode() behavior) + // An overflow will return an error + return n.Float64() +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/scalar.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/scalar.go new file mode 100644 index 000000000000..c78a4c18d122 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/scalar.go @@ -0,0 +1,50 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +// Compare compares floats. The result will be 0 if lhs==rhs, -1 if f < +// rhs, and +1 if f > rhs. +func FloatCompare(lhs, rhs float64) int { + if lhs > rhs { + return 1 + } else if lhs < rhs { + return -1 + } + return 0 +} + +// IntCompare compares integers. The result will be 0 if i==rhs, -1 if i < +// rhs, and +1 if i > rhs. +func IntCompare(lhs, rhs int64) int { + if lhs > rhs { + return 1 + } else if lhs < rhs { + return -1 + } + return 0 +} + +// Compare compares booleans. The result will be 0 if b==rhs, -1 if b < +// rhs, and +1 if b > rhs. +func BoolCompare(lhs, rhs bool) int { + if lhs == rhs { + return 0 + } else if lhs == false { + return -1 + } + return 1 +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/structreflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/structreflect.go new file mode 100644 index 000000000000..4a7bb5c6ebd4 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/structreflect.go @@ -0,0 +1,208 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "fmt" + "reflect" +) + +type structReflect struct { + valueReflect +} + +func (r structReflect) Length() int { + i := 0 + eachStructField(r.Value, func(_ *TypeReflectCacheEntry, s string, value reflect.Value) bool { + i++ + return true + }) + return i +} + +func (r structReflect) Empty() bool { + return eachStructField(r.Value, func(_ *TypeReflectCacheEntry, s string, value reflect.Value) bool { + return false // exit early if the struct is non-empty + }) +} + +func (r structReflect) Get(key string) (Value, bool) { + return r.GetUsing(HeapAllocator, key) +} + +func (r structReflect) GetUsing(a Allocator, key string) (Value, bool) { + if val, ok := r.findJsonNameField(key); ok { + return a.allocValueReflect().mustReuse(val, nil, nil, nil), true + } + return nil, false +} + +func (r structReflect) Has(key string) bool { + _, ok := r.findJsonNameField(key) + return ok +} + +func (r structReflect) Set(key string, val Value) { + fieldEntry, ok := TypeReflectEntryOf(r.Value.Type()).Fields()[key] + if !ok { + panic(fmt.Sprintf("key %s may not be set on struct %T: field does not exist", key, r.Value.Interface())) + } + oldVal := fieldEntry.GetFrom(r.Value) + newVal := reflect.ValueOf(val.Unstructured()) + r.update(fieldEntry, key, oldVal, newVal) +} + +func (r structReflect) Delete(key string) { + fieldEntry, ok := TypeReflectEntryOf(r.Value.Type()).Fields()[key] + if !ok { + panic(fmt.Sprintf("key %s may not be deleted on struct %T: field does not exist", key, r.Value.Interface())) + } + oldVal := fieldEntry.GetFrom(r.Value) + if oldVal.Kind() != reflect.Ptr && !fieldEntry.isOmitEmpty { + panic(fmt.Sprintf("key %s may not be deleted on struct: %T: value is neither a pointer nor an omitempty field", key, r.Value.Interface())) + } + r.update(fieldEntry, key, oldVal, reflect.Zero(oldVal.Type())) +} + +func (r structReflect) update(fieldEntry *FieldCacheEntry, key string, oldVal, newVal reflect.Value) { + if oldVal.CanSet() { + oldVal.Set(newVal) + return + } + + // map items are not addressable, so if a struct is contained in a map, the only way to modify it is + // to write a replacement fieldEntry into the map. + if r.ParentMap != nil { + if r.ParentMapKey == nil { + panic("ParentMapKey must not be nil if ParentMap is not nil") + } + replacement := reflect.New(r.Value.Type()).Elem() + fieldEntry.GetFrom(replacement).Set(newVal) + r.ParentMap.SetMapIndex(*r.ParentMapKey, replacement) + return + } + + // This should never happen since NewValueReflect ensures that the root object reflected on is a pointer and map + // item replacement is handled above. + panic(fmt.Sprintf("key %s may not be modified on struct: %T: struct is not settable", key, r.Value.Interface())) +} + +func (r structReflect) Iterate(fn func(string, Value) bool) bool { + return r.IterateUsing(HeapAllocator, fn) +} + +func (r structReflect) IterateUsing(a Allocator, fn func(string, Value) bool) bool { + vr := a.allocValueReflect() + defer a.Free(vr) + return eachStructField(r.Value, func(e *TypeReflectCacheEntry, s string, value reflect.Value) bool { + return fn(s, vr.mustReuse(value, e, nil, nil)) + }) +} + +func eachStructField(structVal reflect.Value, fn func(*TypeReflectCacheEntry, string, reflect.Value) bool) bool { + for _, fieldCacheEntry := range TypeReflectEntryOf(structVal.Type()).OrderedFields() { + fieldVal := fieldCacheEntry.GetFrom(structVal) + if fieldCacheEntry.CanOmit(fieldVal) { + // omit it + continue + } + ok := fn(fieldCacheEntry.TypeEntry, fieldCacheEntry.JsonName, fieldVal) + if !ok { + return false + } + } + return true +} + +func (r structReflect) Unstructured() interface{} { + // Use number of struct fields as a cheap way to rough estimate map size + result := make(map[string]interface{}, r.Value.NumField()) + r.Iterate(func(s string, value Value) bool { + result[s] = value.Unstructured() + return true + }) + return result +} + +func (r structReflect) Equals(m Map) bool { + return r.EqualsUsing(HeapAllocator, m) +} + +func (r structReflect) EqualsUsing(a Allocator, m Map) bool { + // MapEquals uses zip and is fairly efficient for structReflect + return MapEqualsUsing(a, &r, m) +} + +func (r structReflect) findJsonNameFieldAndNotEmpty(jsonName string) (reflect.Value, bool) { + structCacheEntry, ok := TypeReflectEntryOf(r.Value.Type()).Fields()[jsonName] + if !ok { + return reflect.Value{}, false + } + fieldVal := structCacheEntry.GetFrom(r.Value) + return fieldVal, !structCacheEntry.CanOmit(fieldVal) +} + +func (r structReflect) findJsonNameField(jsonName string) (val reflect.Value, ok bool) { + structCacheEntry, ok := TypeReflectEntryOf(r.Value.Type()).Fields()[jsonName] + if !ok { + return reflect.Value{}, false + } + fieldVal := structCacheEntry.GetFrom(r.Value) + return fieldVal, !structCacheEntry.CanOmit(fieldVal) +} + +func (r structReflect) Zip(other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + return r.ZipUsing(HeapAllocator, other, order, fn) +} + +func (r structReflect) ZipUsing(a Allocator, other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool { + if otherStruct, ok := other.(*structReflect); ok && r.Value.Type() == otherStruct.Value.Type() { + lhsvr, rhsvr := a.allocValueReflect(), a.allocValueReflect() + defer a.Free(lhsvr) + defer a.Free(rhsvr) + return r.structZip(otherStruct, lhsvr, rhsvr, fn) + } + return defaultMapZip(a, &r, other, order, fn) +} + +// structZip provides an optimized zip for structReflect types. The zip is always lexical key ordered since there is +// no additional cost to ordering the zip for structured types. +func (r structReflect) structZip(other *structReflect, lhsvr, rhsvr *valueReflect, fn func(key string, lhs, rhs Value) bool) bool { + lhsVal := r.Value + rhsVal := other.Value + + for _, fieldCacheEntry := range TypeReflectEntryOf(lhsVal.Type()).OrderedFields() { + lhsFieldVal := fieldCacheEntry.GetFrom(lhsVal) + rhsFieldVal := fieldCacheEntry.GetFrom(rhsVal) + lhsOmit := fieldCacheEntry.CanOmit(lhsFieldVal) + rhsOmit := fieldCacheEntry.CanOmit(rhsFieldVal) + if lhsOmit && rhsOmit { + continue + } + var lhsVal, rhsVal Value + if !lhsOmit { + lhsVal = lhsvr.mustReuse(lhsFieldVal, fieldCacheEntry.TypeEntry, nil, nil) + } + if !rhsOmit { + rhsVal = rhsvr.mustReuse(rhsFieldVal, fieldCacheEntry.TypeEntry, nil, nil) + } + if !fn(fieldCacheEntry.JsonName, lhsVal, rhsVal) { + return false + } + } + return true +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/value.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/value.go new file mode 100644 index 000000000000..ea79e3a000e7 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/value.go @@ -0,0 +1,347 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "bytes" + "fmt" + "io" + "strings" + + jsoniter "github.com/json-iterator/go" + "gopkg.in/yaml.v2" +) + +var ( + readPool = jsoniter.NewIterator(jsoniter.ConfigCompatibleWithStandardLibrary).Pool() + writePool = jsoniter.NewStream(jsoniter.ConfigCompatibleWithStandardLibrary, nil, 1024).Pool() +) + +// A Value corresponds to an 'atom' in the schema. It should return true +// for at least one of the IsXXX methods below, or the value is +// considered "invalid" +type Value interface { + // IsMap returns true if the Value is a Map, false otherwise. + IsMap() bool + // IsList returns true if the Value is a List, false otherwise. + IsList() bool + // IsBool returns true if the Value is a bool, false otherwise. + IsBool() bool + // IsInt returns true if the Value is a int64, false otherwise. + IsInt() bool + // IsFloat returns true if the Value is a float64, false + // otherwise. + IsFloat() bool + // IsString returns true if the Value is a string, false + // otherwise. + IsString() bool + // IsMap returns true if the Value is null, false otherwise. + IsNull() bool + + // AsMap converts the Value into a Map (or panic if the type + // doesn't allow it). + AsMap() Map + // AsMapUsing uses the provided allocator and converts the Value + // into a Map (or panic if the type doesn't allow it). + AsMapUsing(Allocator) Map + // AsList converts the Value into a List (or panic if the type + // doesn't allow it). + AsList() List + // AsListUsing uses the provided allocator and converts the Value + // into a List (or panic if the type doesn't allow it). + AsListUsing(Allocator) List + // AsBool converts the Value into a bool (or panic if the type + // doesn't allow it). + AsBool() bool + // AsInt converts the Value into an int64 (or panic if the type + // doesn't allow it). + AsInt() int64 + // AsFloat converts the Value into a float64 (or panic if the type + // doesn't allow it). + AsFloat() float64 + // AsString converts the Value into a string (or panic if the type + // doesn't allow it). + AsString() string + + // Unstructured converts the Value into an Unstructured interface{}. + Unstructured() interface{} +} + +// FromJSON is a helper function for reading a JSON document. +func FromJSON(input []byte) (Value, error) { + return FromJSONFast(input) +} + +// FromJSONFast is a helper function for reading a JSON document. +func FromJSONFast(input []byte) (Value, error) { + iter := readPool.BorrowIterator(input) + defer readPool.ReturnIterator(iter) + return ReadJSONIter(iter) +} + +// ToJSON is a helper function for producing a JSon document. +func ToJSON(v Value) ([]byte, error) { + buf := bytes.Buffer{} + stream := writePool.BorrowStream(&buf) + defer writePool.ReturnStream(stream) + WriteJSONStream(v, stream) + b := stream.Buffer() + err := stream.Flush() + // Help jsoniter manage its buffers--without this, the next + // use of the stream is likely to require an allocation. Look + // at the jsoniter stream code to understand why. They were probably + // optimizing for folks using the buffer directly. + stream.SetBuffer(b[:0]) + return buf.Bytes(), err +} + +// ReadJSONIter reads a Value from a JSON iterator. +func ReadJSONIter(iter *jsoniter.Iterator) (Value, error) { + v := iter.Read() + if iter.Error != nil && iter.Error != io.EOF { + return nil, iter.Error + } + return NewValueInterface(v), nil +} + +// WriteJSONStream writes a value into a JSON stream. +func WriteJSONStream(v Value, stream *jsoniter.Stream) { + stream.WriteVal(v.Unstructured()) +} + +// ToYAML marshals a value as YAML. +func ToYAML(v Value) ([]byte, error) { + return yaml.Marshal(v.Unstructured()) +} + +// Equals returns true iff the two values are equal. +func Equals(lhs, rhs Value) bool { + return EqualsUsing(HeapAllocator, lhs, rhs) +} + +// EqualsUsing uses the provided allocator and returns true iff the two values are equal. +func EqualsUsing(a Allocator, lhs, rhs Value) bool { + if lhs.IsFloat() || rhs.IsFloat() { + var lf float64 + if lhs.IsFloat() { + lf = lhs.AsFloat() + } else if lhs.IsInt() { + lf = float64(lhs.AsInt()) + } else { + return false + } + var rf float64 + if rhs.IsFloat() { + rf = rhs.AsFloat() + } else if rhs.IsInt() { + rf = float64(rhs.AsInt()) + } else { + return false + } + return lf == rf + } + if lhs.IsInt() { + if rhs.IsInt() { + return lhs.AsInt() == rhs.AsInt() + } + return false + } else if rhs.IsInt() { + return false + } + if lhs.IsString() { + if rhs.IsString() { + return lhs.AsString() == rhs.AsString() + } + return false + } else if rhs.IsString() { + return false + } + if lhs.IsBool() { + if rhs.IsBool() { + return lhs.AsBool() == rhs.AsBool() + } + return false + } else if rhs.IsBool() { + return false + } + if lhs.IsList() { + if rhs.IsList() { + lhsList := lhs.AsListUsing(a) + defer a.Free(lhsList) + rhsList := rhs.AsListUsing(a) + defer a.Free(rhsList) + return lhsList.EqualsUsing(a, rhsList) + } + return false + } else if rhs.IsList() { + return false + } + if lhs.IsMap() { + if rhs.IsMap() { + lhsList := lhs.AsMapUsing(a) + defer a.Free(lhsList) + rhsList := rhs.AsMapUsing(a) + defer a.Free(rhsList) + return lhsList.EqualsUsing(a, rhsList) + } + return false + } else if rhs.IsMap() { + return false + } + if lhs.IsNull() { + if rhs.IsNull() { + return true + } + return false + } else if rhs.IsNull() { + return false + } + // No field is set, on either objects. + return true +} + +// ToString returns a human-readable representation of the value. +func ToString(v Value) string { + if v.IsNull() { + return "null" + } + switch { + case v.IsFloat(): + return fmt.Sprintf("%v", v.AsFloat()) + case v.IsInt(): + return fmt.Sprintf("%v", v.AsInt()) + case v.IsString(): + return fmt.Sprintf("%q", v.AsString()) + case v.IsBool(): + return fmt.Sprintf("%v", v.AsBool()) + case v.IsList(): + strs := []string{} + list := v.AsList() + for i := 0; i < list.Length(); i++ { + strs = append(strs, ToString(list.At(i))) + } + return "[" + strings.Join(strs, ",") + "]" + case v.IsMap(): + strs := []string{} + v.AsMap().Iterate(func(k string, v Value) bool { + strs = append(strs, fmt.Sprintf("%v=%v", k, ToString(v))) + return true + }) + return strings.Join(strs, "") + } + // No field is set, on either objects. + return "{{undefined}}" +} + +// Less provides a total ordering for Value (so that they can be sorted, even +// if they are of different types). +func Less(lhs, rhs Value) bool { + return Compare(lhs, rhs) == -1 +} + +// Compare provides a total ordering for Value (so that they can be +// sorted, even if they are of different types). The result will be 0 if +// v==rhs, -1 if v < rhs, and +1 if v > rhs. +func Compare(lhs, rhs Value) int { + return CompareUsing(HeapAllocator, lhs, rhs) +} + +// CompareUsing uses the provided allocator and provides a total +// ordering for Value (so that they can be sorted, even if they +// are of different types). The result will be 0 if v==rhs, -1 +// if v < rhs, and +1 if v > rhs. +func CompareUsing(a Allocator, lhs, rhs Value) int { + if lhs.IsFloat() { + if !rhs.IsFloat() { + // Extra: compare floats and ints numerically. + if rhs.IsInt() { + return FloatCompare(lhs.AsFloat(), float64(rhs.AsInt())) + } + return -1 + } + return FloatCompare(lhs.AsFloat(), rhs.AsFloat()) + } else if rhs.IsFloat() { + // Extra: compare floats and ints numerically. + if lhs.IsInt() { + return FloatCompare(float64(lhs.AsInt()), rhs.AsFloat()) + } + return 1 + } + + if lhs.IsInt() { + if !rhs.IsInt() { + return -1 + } + return IntCompare(lhs.AsInt(), rhs.AsInt()) + } else if rhs.IsInt() { + return 1 + } + + if lhs.IsString() { + if !rhs.IsString() { + return -1 + } + return strings.Compare(lhs.AsString(), rhs.AsString()) + } else if rhs.IsString() { + return 1 + } + + if lhs.IsBool() { + if !rhs.IsBool() { + return -1 + } + return BoolCompare(lhs.AsBool(), rhs.AsBool()) + } else if rhs.IsBool() { + return 1 + } + + if lhs.IsList() { + if !rhs.IsList() { + return -1 + } + lhsList := lhs.AsListUsing(a) + defer a.Free(lhsList) + rhsList := rhs.AsListUsing(a) + defer a.Free(rhsList) + return ListCompareUsing(a, lhsList, rhsList) + } else if rhs.IsList() { + return 1 + } + if lhs.IsMap() { + if !rhs.IsMap() { + return -1 + } + lhsMap := lhs.AsMapUsing(a) + defer a.Free(lhsMap) + rhsMap := rhs.AsMapUsing(a) + defer a.Free(rhsMap) + return MapCompareUsing(a, lhsMap, rhsMap) + } else if rhs.IsMap() { + return 1 + } + if lhs.IsNull() { + if !rhs.IsNull() { + return -1 + } + return 0 + } else if rhs.IsNull() { + return 1 + } + + // Invalid Value-- nothing is set. + return 0 +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valuereflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valuereflect.go new file mode 100644 index 000000000000..05e70debaef3 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valuereflect.go @@ -0,0 +1,294 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "encoding/base64" + "fmt" + "reflect" +) + +// NewValueReflect creates a Value backed by an "interface{}" type, +// typically an structured object in Kubernetes world that is uses reflection to expose. +// The provided "interface{}" value must be a pointer so that the value can be modified via reflection. +// The provided "interface{}" may contain structs and types that are converted to Values +// by the jsonMarshaler interface. +func NewValueReflect(value interface{}) (Value, error) { + if value == nil { + return NewValueInterface(nil), nil + } + v := reflect.ValueOf(value) + if v.Kind() != reflect.Ptr { + // The root value to reflect on must be a pointer so that map.Set() and map.Delete() operations are possible. + return nil, fmt.Errorf("value provided to NewValueReflect must be a pointer") + } + return wrapValueReflect(v, nil, nil) +} + +// wrapValueReflect wraps the provide reflect.Value as a value. If parent in the data tree is a map, parentMap +// and parentMapKey must be provided so that the returned value may be set and deleted. +func wrapValueReflect(value reflect.Value, parentMap, parentMapKey *reflect.Value) (Value, error) { + val := HeapAllocator.allocValueReflect() + return val.reuse(value, nil, parentMap, parentMapKey) +} + +// wrapValueReflect wraps the provide reflect.Value as a value, and panics if there is an error. If parent in the data +// tree is a map, parentMap and parentMapKey must be provided so that the returned value may be set and deleted. +func mustWrapValueReflect(value reflect.Value, parentMap, parentMapKey *reflect.Value) Value { + v, err := wrapValueReflect(value, parentMap, parentMapKey) + if err != nil { + panic(err) + } + return v +} + +// the value interface doesn't care about the type for value.IsNull, so we can use a constant +var nilType = reflect.TypeOf(&struct{}{}) + +// reuse replaces the value of the valueReflect. If parent in the data tree is a map, parentMap and parentMapKey +// must be provided so that the returned value may be set and deleted. +func (r *valueReflect) reuse(value reflect.Value, cacheEntry *TypeReflectCacheEntry, parentMap, parentMapKey *reflect.Value) (Value, error) { + if cacheEntry == nil { + cacheEntry = TypeReflectEntryOf(value.Type()) + } + if cacheEntry.CanConvertToUnstructured() { + u, err := cacheEntry.ToUnstructured(value) + if err != nil { + return nil, err + } + if u == nil { + value = reflect.Zero(nilType) + } else { + value = reflect.ValueOf(u) + } + } + r.Value = dereference(value) + r.ParentMap = parentMap + r.ParentMapKey = parentMapKey + r.kind = kind(r.Value) + return r, nil +} + +// mustReuse replaces the value of the valueReflect and panics if there is an error. If parent in the data tree is a +// map, parentMap and parentMapKey must be provided so that the returned value may be set and deleted. +func (r *valueReflect) mustReuse(value reflect.Value, cacheEntry *TypeReflectCacheEntry, parentMap, parentMapKey *reflect.Value) Value { + v, err := r.reuse(value, cacheEntry, parentMap, parentMapKey) + if err != nil { + panic(err) + } + return v +} + +func dereference(val reflect.Value) reflect.Value { + kind := val.Kind() + if (kind == reflect.Interface || kind == reflect.Ptr) && !safeIsNil(val) { + return val.Elem() + } + return val +} + +type valueReflect struct { + ParentMap *reflect.Value + ParentMapKey *reflect.Value + Value reflect.Value + kind reflectType +} + +func (r valueReflect) IsMap() bool { + return r.kind == mapType || r.kind == structMapType +} + +func (r valueReflect) IsList() bool { + return r.kind == listType +} + +func (r valueReflect) IsBool() bool { + return r.kind == boolType +} + +func (r valueReflect) IsInt() bool { + return r.kind == intType || r.kind == uintType +} + +func (r valueReflect) IsFloat() bool { + return r.kind == floatType +} + +func (r valueReflect) IsString() bool { + return r.kind == stringType || r.kind == byteStringType +} + +func (r valueReflect) IsNull() bool { + return r.kind == nullType +} + +type reflectType = int + +const ( + mapType = iota + structMapType + listType + intType + uintType + floatType + stringType + byteStringType + boolType + nullType +) + +func kind(v reflect.Value) reflectType { + typ := v.Type() + rk := typ.Kind() + switch rk { + case reflect.Map: + if v.IsNil() { + return nullType + } + return mapType + case reflect.Struct: + return structMapType + case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8: + return intType + case reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uint8: + // Uint64 deliberately excluded, see valueUnstructured.Int. + return uintType + case reflect.Float64, reflect.Float32: + return floatType + case reflect.String: + return stringType + case reflect.Bool: + return boolType + case reflect.Slice: + if v.IsNil() { + return nullType + } + elemKind := typ.Elem().Kind() + if elemKind == reflect.Uint8 { + return byteStringType + } + return listType + case reflect.Chan, reflect.Func, reflect.Ptr, reflect.UnsafePointer, reflect.Interface: + if v.IsNil() { + return nullType + } + panic(fmt.Sprintf("unsupported type: %v", v.Type())) + default: + panic(fmt.Sprintf("unsupported type: %v", v.Type())) + } +} + +// TODO find a cleaner way to avoid panics from reflect.IsNil() +func safeIsNil(v reflect.Value) bool { + k := v.Kind() + switch k { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice: + return v.IsNil() + } + return false +} + +func (r valueReflect) AsMap() Map { + return r.AsMapUsing(HeapAllocator) +} + +func (r valueReflect) AsMapUsing(a Allocator) Map { + switch r.kind { + case structMapType: + v := a.allocStructReflect() + v.valueReflect = r + return v + case mapType: + v := a.allocMapReflect() + v.valueReflect = r + return v + default: + panic("value is not a map or struct") + } +} + +func (r valueReflect) AsList() List { + return r.AsListUsing(HeapAllocator) +} + +func (r valueReflect) AsListUsing(a Allocator) List { + if r.IsList() { + v := a.allocListReflect() + v.Value = r.Value + return v + } + panic("value is not a list") +} + +func (r valueReflect) AsBool() bool { + if r.IsBool() { + return r.Value.Bool() + } + panic("value is not a bool") +} + +func (r valueReflect) AsInt() int64 { + if r.kind == intType { + return r.Value.Int() + } + if r.kind == uintType { + return int64(r.Value.Uint()) + } + + panic("value is not an int") +} + +func (r valueReflect) AsFloat() float64 { + if r.IsFloat() { + return r.Value.Float() + } + panic("value is not a float") +} + +func (r valueReflect) AsString() string { + switch r.kind { + case stringType: + return r.Value.String() + case byteStringType: + return base64.StdEncoding.EncodeToString(r.Value.Bytes()) + } + panic("value is not a string") +} + +func (r valueReflect) Unstructured() interface{} { + val := r.Value + switch { + case r.IsNull(): + return nil + case val.Kind() == reflect.Struct: + return structReflect{r}.Unstructured() + case val.Kind() == reflect.Map: + return mapReflect{valueReflect: r}.Unstructured() + case r.IsList(): + return listReflect{r.Value}.Unstructured() + case r.IsString(): + return r.AsString() + case r.IsInt(): + return r.AsInt() + case r.IsBool(): + return r.AsBool() + case r.IsFloat(): + return r.AsFloat() + default: + panic(fmt.Sprintf("value of type %s is not a supported by value reflector", val.Type())) + } +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valueunstructured.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valueunstructured.go new file mode 100644 index 000000000000..ac5a926285d3 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/valueunstructured.go @@ -0,0 +1,178 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "fmt" +) + +// NewValueInterface creates a Value backed by an "interface{}" type, +// typically an unstructured object in Kubernetes world. +// interface{} must be one of: map[string]interface{}, map[interface{}]interface{}, []interface{}, int types, float types, +// string or boolean. Nested interface{} must also be one of these types. +func NewValueInterface(v interface{}) Value { + return Value(HeapAllocator.allocValueUnstructured().reuse(v)) +} + +type valueUnstructured struct { + Value interface{} +} + +// reuse replaces the value of the valueUnstructured. +func (vi *valueUnstructured) reuse(value interface{}) Value { + vi.Value = value + return vi +} + +func (v valueUnstructured) IsMap() bool { + if _, ok := v.Value.(map[string]interface{}); ok { + return true + } + if _, ok := v.Value.(map[interface{}]interface{}); ok { + return true + } + return false +} + +func (v valueUnstructured) AsMap() Map { + return v.AsMapUsing(HeapAllocator) +} + +func (v valueUnstructured) AsMapUsing(_ Allocator) Map { + if v.Value == nil { + panic("invalid nil") + } + switch t := v.Value.(type) { + case map[string]interface{}: + return mapUnstructuredString(t) + case map[interface{}]interface{}: + return mapUnstructuredInterface(t) + } + panic(fmt.Errorf("not a map: %#v", v)) +} + +func (v valueUnstructured) IsList() bool { + if v.Value == nil { + return false + } + _, ok := v.Value.([]interface{}) + return ok +} + +func (v valueUnstructured) AsList() List { + return v.AsListUsing(HeapAllocator) +} + +func (v valueUnstructured) AsListUsing(_ Allocator) List { + return listUnstructured(v.Value.([]interface{})) +} + +func (v valueUnstructured) IsFloat() bool { + if v.Value == nil { + return false + } else if _, ok := v.Value.(float64); ok { + return true + } else if _, ok := v.Value.(float32); ok { + return true + } + return false +} + +func (v valueUnstructured) AsFloat() float64 { + if f, ok := v.Value.(float32); ok { + return float64(f) + } + return v.Value.(float64) +} + +func (v valueUnstructured) IsInt() bool { + if v.Value == nil { + return false + } else if _, ok := v.Value.(int); ok { + return true + } else if _, ok := v.Value.(int8); ok { + return true + } else if _, ok := v.Value.(int16); ok { + return true + } else if _, ok := v.Value.(int32); ok { + return true + } else if _, ok := v.Value.(int64); ok { + return true + } else if _, ok := v.Value.(uint); ok { + return true + } else if _, ok := v.Value.(uint8); ok { + return true + } else if _, ok := v.Value.(uint16); ok { + return true + } else if _, ok := v.Value.(uint32); ok { + return true + } + return false +} + +func (v valueUnstructured) AsInt() int64 { + if i, ok := v.Value.(int); ok { + return int64(i) + } else if i, ok := v.Value.(int8); ok { + return int64(i) + } else if i, ok := v.Value.(int16); ok { + return int64(i) + } else if i, ok := v.Value.(int32); ok { + return int64(i) + } else if i, ok := v.Value.(uint); ok { + return int64(i) + } else if i, ok := v.Value.(uint8); ok { + return int64(i) + } else if i, ok := v.Value.(uint16); ok { + return int64(i) + } else if i, ok := v.Value.(uint32); ok { + return int64(i) + } + return v.Value.(int64) +} + +func (v valueUnstructured) IsString() bool { + if v.Value == nil { + return false + } + _, ok := v.Value.(string) + return ok +} + +func (v valueUnstructured) AsString() string { + return v.Value.(string) +} + +func (v valueUnstructured) IsBool() bool { + if v.Value == nil { + return false + } + _, ok := v.Value.(bool) + return ok +} + +func (v valueUnstructured) AsBool() bool { + return v.Value.(bool) +} + +func (v valueUnstructured) IsNull() bool { + return v.Value == nil +} + +func (v valueUnstructured) Unstructured() interface{} { + return v.Value +}